zoukankan      html  css  js  c++  java
  • CF822F Madness

    题意:给你一棵边权都为1的树,要求选择互不相交的若干条路径,这些路径包含有所有点。

    在每一条路径上选择一条边,放置一个动点,设置一个方向,它开始在该路径上来回运动,速度为1。每个点上都有一个停表,当有一个动点经过这个点时它清零。设res_i表示i停表的历史最大显示时间。设得res_1,res_2,res_3,……序列的字典序最小。

    n<=100。(数据范围有时候是唬人的)

    标程:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=105;
     4 int n,u[N],v[N],head[N],rd[N],cnt,To[N];
     5 double ans[N];
     6 struct node{int to,next;}num[N*2];
     7 void add(int x,int y)
     8 {num[++cnt].to=y;num[cnt].next=head[x];head[x]=cnt;}
     9 void dfs(int x,int fa,double lst)
    10 {
    11     double e=2.0/rd[x];//注意用2.0/而不是2/! 
    12     for (int i=head[x];i;i=num[i].next)
    13       if (num[i].to!=fa)
    14       {
    15             lst+=e;while (lst>2) lst-=2;
    16           int id=(i+1)/2;
    17             if (lst<=1) To[id]=x,ans[id]=lst;
    18              else To[id]=num[i].to,ans[id]=lst-1;
    19          dfs(num[i].to,x,lst+1);
    20       }
    21 }
    22 int main()
    23 {
    24     scanf("%d",&n);
    25     for (int i=1;i<n;i++) scanf("%d%d",&u[i],&v[i]),add(u[i],v[i]),add(v[i],u[i]),rd[u[i]]++,rd[v[i]]++;
    26     dfs(1,-1,0);
    27     printf("%d
    ",n-1);
    28     for (int i=1;i<n;i++) printf("1 %d %d %d %.8lf
    ",i,u[i]+v[i]-To[i],To[i],ans[i]);
    29     return 0;
    30 }

    易错点:1.注意double的除法。

    2.注意lst表示到动点到儿子的距离。往下一层dfs的时候注意变更。

    题解:贪心+构造

    发现当每一条边都独立为一条路径时,经过路径上每一个点的时间间隔是最小的。

    因此发现某动点一来一回时间间隔为2,对于i点的停表,历史最大时间为2/deg[i]。一定可以构造出来。

    dfs按照树的结构构造一下即可。

  • 相关阅读:
    hdu1238 Substrings
    CCF试题:高速公路(Targin)
    hdu 1269 迷宫城堡(Targin算法)
    hdu 1253 胜利大逃亡
    NYOJ 55 懒省事的小明
    HDU 1024 Max Sum Plus Plus
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1257 最少拦截系统
    HDU 1069 Monkey and Banana
    HDU 1104 Remainder
  • 原文地址:https://www.cnblogs.com/Scx117/p/9067506.html
Copyright © 2011-2022 走看看