CodeForces - 804C Ice cream coloring (dfs)
Posted asdfsag
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 804C Ice cream coloring (dfs)相关的知识,希望对你有一定的参考价值。
注意到每种冰激凌在树上的结点是连通的。如果整棵树是一条链的话,那么问题就转化成了经典的一维区间染色问题。
所以我们要考虑如何把链上的情况推广到树上的情况。
一开始我想把欧拉序转换成区间来做,然而发现并不可行,因为一颗连续的子树可能会形成许多个连续的区间,需要另辟蹊径。
任选一个结点作为树根,可以发现,从根节点到任意叶子结点所形成的链都可以转化成一维的区间染色问题,且各个分支互不影响,所以从根节点dfs一遍,每次贪心选择没有出现过的最小颜色就行了。
注意一个坑点:有的冰激凌可能不会在树上出现,需要单独染色。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=3e5+10,inf=0x3f3f3f3f; 5 int hd[N],ne,n,m,c[N],lg[N],col[N]; 6 vector<int> vec[N]; 7 struct E {int v,nxt;} e[N<<1]; 8 void link(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;} 9 int lb(int x) {return x&-x;} 10 void add(int u,int x) {for(; u<=m; u+=lb(u))c[u]+=x;} 11 int getmi() {int u=0; for(int i=1<<lg[m]; i; i>>=1)if(u+i<=m&&c[u+i]==i)u+=i; return u+1;} 12 void dfs(int u,int f) { 13 for(int x:vec[u])if(col[x])add(col[x],1); 14 for(int x:vec[u])if(!col[x])col[x]=getmi(),add(col[x],1); 15 for(int x:vec[u])add(col[x],-1); 16 for(int i=hd[u]; ~i; i=e[i].nxt) { 17 int v=e[i].v; 18 if(v==f)continue; 19 dfs(v,u); 20 } 21 } 22 int main() { 23 lg[0]=-1; 24 for(int i=1; i<N; ++i)lg[i]=lg[i>>1]+1; 25 memset(hd,-1,sizeof hd),ne=0; 26 scanf("%d%d",&n,&m); 27 for(int i=1; i<=n; ++i) { 28 int k; 29 scanf("%d",&k); 30 while(k--) { 31 int x; 32 scanf("%d",&x); 33 vec[i].push_back(x); 34 } 35 } 36 for(int i=1; i<n; ++i) { 37 int u,v; 38 scanf("%d%d",&u,&v); 39 link(u,v); 40 link(v,u); 41 } 42 dfs(1,0); 43 for(int i=1; i<=m; ++i)if(!col[i])col[i]=1; 44 int ans=0; 45 for(int i=1; i<=m; ++i)ans=max(ans,col[i]); 46 printf("%d ",ans); 47 for(int i=1; i<=m; ++i)printf("%d%c",col[i]," "[i==m]); 48 return 0; 49 }
以上是关于CodeForces - 804C Ice cream coloring (dfs)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces K. Ice Skating(求强连通分量)
codeforces 686A A. Free Ice Cream(水题)
CodeForces 686A Free Ice Cream (水题模拟)