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 采集糖果

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 采集糖果

bzoj1589 [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果

XJOI 3605 考完吃糖(DAG图dfs)