【洛谷P2921】[USACO08DEC]在农场万圣节

在农场万圣节Trick or Treat on the Farm

题目链接

题解:
首先,将原图缩点,变为DAG,

然后在DAG上记忆化搜索即可

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define N 100010
 6 #define reset(a) memset(a,0,sizeof(a))
 7 int n,next[N],belong[N],num;
 8 int Next[N],f[N],size[N];
 9 int dfn[N],low[N],cnt;
10 int stack[N],top;
11 bool ins[N];
12 void dfs(int t){
13     dfn[t]=low[t]=++cnt;
14     stack[++top]=t;
15     ins[t]=1;
16     int v=next[t];
17     if(!dfn[v]){
18         dfs(v);
19         low[t]=min(low[t],low[v]);
20     }
21     else if(ins[v])
22         low[t]=min(low[t],dfn[v]);
23     if(low[t]==dfn[t]){
24         num++;
25         size[num]++;
26         while(stack[top]!=t){
27             size[num]++;
28             int u=stack[top];
29             belong[u]=num;
30             ins[u]=0;
31             top--;
32         }
33         top--;
34         ins[t]=0;
35         belong[t]=num;
36     }
37 }
38 int Dfs(int t){
39     if(f[t]) return f[t];
40     if(!Next[t]) return f[t]=size[t];
41     return f[t]=size[t]+Dfs(Next[t]);
42 }
43 int main()
44 {
45     scanf("%d",&n);
46     for(int i=1;i<=n;i++)
47      scanf("%d",&next[i]);
48     for(int i=1;i<=n;i++)
49      if(!dfn[i]) dfs(i);
50     for(int i=1;i<=n;i++)
51      if(belong[i]!=belong[next[i]])
52       Next[belong[i]]=belong[next[i]];
53     for(int i=1;i<=n;i++){
54         if(!f[belong[i]])
55          Dfs(belong[i]);
56         printf("%d\n",f[belong[i]]);
57     }
58     return 0;        
59 }

 

posted @ 2018-07-24 16:53  yjk  阅读(163)  评论(0编辑  收藏  举报