【dfs+理解题意+构造】【待重做】codeforces E. Ice cream coloring

http://codeforces.com/contest/805/problem/E

【题意】

染色数是很好确定,最少染色数是max(si)(最小为1,即使所有的si都为0,这样是单节点树形成的森林需要1种颜色),关键是确定染色方案。

一开始没看出来树有什么用,但其实一句话很关键:Vertices which have the i-th (1 ≤ i ≤ m) type of ice cream form a connected subgraph.

也就是说在原来的图中,含有相同的冰淇淋的点是一个 联通子图。那么比如1,2在一个点,1,3在一个点,那么2,3便不可能在另一个点了,因为那样将会形成一个环,也就是说这个图不再是树了。

因为每种冰淇淋所在的所有点在这颗树上是一个连通块,也就是说,沿着树搜索下去,不可能出现已经染过色且父亲中没有的冰淇淋重新出现的问题。于是就可以直接贪心构造一波就行了。” 然而这里还是每太明白,为什么这样构造......

 

【Accepted】

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <cmath>
  4 #include <vector>
  5 #include <algorithm>
  6 #include <set>
  7 #include <map>
  8 #include <queue>
  9 #include <deque>
 10 #include <stack>
 11 #include <string>
 12 #include <bitset>
 13 #include <ctime>
 14 #include<algorithm>
 15 #include<cstring>
 16 using namespace std;
 17 typedef long long ll;
 18 int n,m;
 19 const int maxn=3e5+5;
 20 vector<int> s[maxn];
 21 int num[maxn];
 22 int c[maxn];
 23 struct node
 24 {
 25     int to;
 26     int nxt;
 27 }edge[maxn<<1];
 28 int head[maxn];
 29 int tot;
 30 int res;
 31 void add(int u,int v)
 32 {
 33     edge[tot].nxt=head[u];
 34     edge[tot].to=v;
 35     head[u]=tot++;
 36 }
 37 
 38 void Init()
 39 {
 40     res=1;
 41     tot=0;
 42     memset(c,0,sizeof(c));
 43     memset(head,-1,sizeof(head));
 44 }
 45 void dfs(int u,int pre)
 46 {
 47     res=max(res,num[u]);
 48     set<int> t;
 49     t.clear();
 50     for(int i=0;i<num[u];i++)
 51     {
 52         int v=s[u][i];
 53         if(c[v])
 54         {
 55             t.insert(c[v]);
 56         }
 57     }
 58     int temp=0;
 59     for(int i=0;i<num[u];i++)
 60     {
 61         int v=s[u][i];
 62         if(!c[v])
 63         {
 64             temp++;
 65             while(t.count(temp))
 66             {
 67                 temp++;
 68             }
 69             c[v]=temp;
 70         }
 71     }
 72     for(int i=head[u];i!=-1;i=edge[i].nxt)
 73     {
 74         int to=edge[i].to;
 75         if(to!=pre)
 76         {
 77             dfs(to,u);
 78         }
 79     }
 80 }
 81 int main()
 82 {
 83     while(~scanf("%d%d",&n,&m))
 84     {
 85         Init();
 86         for(int i=1;i<=n;i++)
 87         {
 88             scanf("%d",&num[i]);
 89             s[i].clear();
 90             for(int k=0;k<num[i];k++)
 91             {
 92                 int x;
 93                 scanf("%d",&x);
 94                 s[i].push_back(x);
 95             }
 96         }
 97         int u,v;
 98         for(int i=0;i<n-1;i++)
 99         {
100             scanf("%d%d",&u,&v);
101             add(u,v);
102             add(v,u);
103         }
104         dfs(1,0);
105         for(int i=1;i<=m;i++)
106         {
107             if(!c[i])
108             {
109                 c[i]=1;
110             }
111         }
112         cout<<res<<endl;
113         cout<<c[1];
114         for(int i=2;i<=m;i++)
115         {
116             cout<<" "<<c[i];
117         }
118         cout<<endl;    
119     }
120     return 0;
121  } 
View Code

 

posted @ 2017-06-05 21:28  shulin15  阅读(285)  评论(0编辑  收藏  举报