1. 程式人生 > >【DFS】采集糖果

【DFS】采集糖果

while getc i++ == ++ dfs pan turn n)

讀入後存儲所有反向邊,這些反向邊一定構成一些基環外向樹,每頭牛可以采集到的糖果數等於基環大小加上它的深度

利用並查集可以在輸入的同時求出所有環,然後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】采集糖果