DFS采集糖果
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DFS采集糖果相关的知识,希望对你有一定的参考价值。
读入后存储所有反向边,这些反向边一定构成一些基环外向树,每头牛可以采集到的糖果数等于基环大小加上它的深度
利用并查集可以在输入的同时求出所有环,然后DFS所有环上的所有外向树即可
1 #include <cstdio> 2 struct E{int next,to;}e[100001]; 3 int n,x,esz=1,csz=1,head[100001],root[100001],pre[100001],bak[100001],len[100001],ans[100001]; 4 void read(int &x) 5 { 6 char ch=getchar();x=0; 7 for (;ch<‘0‘||ch>‘9‘;ch=getchar()); 8 for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; 9 } 10 void insert(int u,int v) 11 { 12 e[esz].next=head[u]; 13 head[u]=esz; 14 e[esz].to=v; 15 esz++; 16 } 17 int find(int x) 18 { 19 if (pre[x]==0) return x; 20 return pre[x]=find(pre[x]); 21 } 22 void dfs(int x,int sz) 23 { 24 ans[x]=sz; 25 for (int i=head[x];i;i=e[i].next) 26 dfs(e[i].to,sz+1); 27 } 28 int main() 29 { 30 read(n); 31 for (int i=1;i<=n;i++) 32 { 33 //x->i 34 read(x); 35 if (find(x)==i) 36 { 37 root[csz]=x; 38 csz++; 39 } 40 else 41 { 42 insert(x,i); 43 bak[i]=x; 44 pre[find(i)]=find(x); 45 } 46 } 47 for (int i=1;i<csz;i++) 48 { 49 int lj=0,sz=1,j=root[i]; 50 while (j=bak[j]) sz++; 51 j=root[i]; 52 do 53 { 54 ans[j]=sz; 55 for (int k=head[j];k;k=e[k].next) 56 if (e[k].to!=lj) dfs(e[k].to,sz+1); 57 lj=j; 58 }while (j=bak[j]); 59 } 60 for (int i=1;i<=n;i++) printf("%d\n",ans[i]); 61 }
以上是关于DFS采集糖果的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1589: [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果
bzoj1589/Usaco2008 DecTrick or Treat on the Farm 采集糖果——拓扑排序
[BZOJ1589][Usaco2008 Dec]Trick or Treat on the Farm 采集糖果