【USACO】Strolling Cows
阿新 • • 發佈:2020-08-05
給定有 \(n\) 個點 \(n\) 條邊的有向圖,每個點的出度都為 \(1\),求圖中的最大環。
顯然入度為 \(0\) 的點不可能為最大環上的點,所以考慮刪點。
然後遍歷每個連通塊記錄最大即可。
(史上最短題解?)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #define N 30010 using namespace std; int n,to[N],ru[N],ans=1; bool vis[N]; int read(){ int x=0,f=1;char c=getchar(); while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0' && c<='9') x=x*10+c-48,c=getchar(); return x*f; } int main(){ //freopen("stroll.in","r",stdin); //freopen("stroll.out","w",stdout); n=read(); memset(ru,0,sizeof(ru)); memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) to[i]=read(),++ru[to[i]]; for(int i=1;i<=n;i++){//刪點。 if(vis[i]) continue; int now=i; while(!ru[now]){ vis[now]=true; --ru[to[now]]; now=to[now]; } } int ans=1; for(int i=1;i<=n;i++){//遍歷連通塊。 if(vis[i]) continue; vis[i]=true; int now=to[i],sum=1; while(now!=i) ++sum,vis[now]=true,now=to[now]; ans=max(ans,sum); } printf("%d\n",ans); //fclose(stdin);fclose(stdout); return 0; }