乍一看题,搜索。
可以暴力找环,可是我总觉得要超时。
然后想了一种极其猥琐的打法。
首先可以想到,没有其他人能传递到的点肯定不在环内。因为没有别人能把生日告诉他,因此他绝对不可能知道自己的生日。
然后记录每一个点的入度,为0的删除,并删掉与它有边相连的点。如果该点的入度也为0,那么继续重复此操作(其实就是拓扑)。
然后对剩下的点进行找最小环的操作即可。
总体复杂度大体为O(n)吧。
CODE
#include<cstdio> #include<iostream> using namespace std; inline void read(int &x) { x=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); } const int N=200005; int a[N],r[N],i,j,n,x,tot=1e9,len; bool f[N]; void dfs(int x) { int k=a[x]; r[k]--; if (!r[k]&&!f[k]) f[k]=1,dfs(k); } int main() { read(n); for (i=1;i<=n;++i) { read(a[i]); r[a[i]]++; } for (i=1;i<=n;++i) if (!r[i]&&!f[i]) f[i]=1,dfs(i); for (i=1;i<=n;++i) if (!f[i]) { f[i]=1; len=1; j=a[i]; while (j!=i) f[j]=1,len++,j=a[j]; tot=min(tot,len); } printf("%d",tot); return 0; }