https://ac.nowcoder.com/acm/contest/3007/B
此题我不但又双叒叕做麻烦了,而且达到了我麻烦的巅峰
tarjan重构图然后新图上拓扑dp
吐血。。。
因为他是n个点n条边,且每个点只有一条出边
所以该图是一个基环内向树
从一个点出发,要么走到链的一段,要么停在一个环上
只需要记忆化dfs找出那个环即可
注意可能有自环
稍稍借鉴了一下tarja的思路
#include<cstdio> #include<algorithm> using namespace std; #define N 1000001 int to[N],f[N]; bool vis[N]; int dfn[N],tim; int sum,tag; void dfs(int x) { vis[x]=true; dfn[x]=++tim; if(!dfn[to[x]]) { dfs(to[x]); if(tag) { f[x]=sum; if(tag==x) tag=0; } else f[x]=f[to[x]]+1; } else if(vis[to[x]]) { sum=dfn[x]-dfn[to[x]]+1; f[x]=sum; tag=to[x]; if(x==tag) tag=0; } else f[x]=f[to[x]]+1; vis[x]=false; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&to[i]); for(int i=1;i<=n;++i) if(!dfn[i]) dfs(i); int ans=0; for(int i=1;i<=n;++i) ans=max(ans,f[i]); printf("%d",ans); }