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按照树的结构构造一下即可。

  • 相关阅读:
    Linux-文件编程
    Linux-编程基础
    Linux-系统管理
    Linux-命令
    图解HTTP-笔记
    微信小程序发送红包功能。填坑记录
    PHP中使用raw格式发送POST请求
    论一个PHP项目上线的注意点
    PHP CURL 模拟form表单上传遇到的小坑
    使用php的curl函数post返回值为301永久迁移的问题。(301 Moved Permanently)
  • 原文地址:https://www.cnblogs.com/Scx117/p/9067506.html
Copyright © 2011-2022 走看看