题目就是要求一个图中的最小环。
因为每个点的出度一定等于 1 ,所以每个大小不为 1 的强连通分量必定是一个环。
那么,那些大小不为 1 的强连通分量中大小最小的值就是答案了。
这里使用 Tarjan 算法来求强连通分量。
#include <iostream>
#include <cstdio>
const int Inf = 0x3f3f3f3f;
const int MaxN = 2e5 + 5;
int N, Index, Ans = Inf, Tail;
int Dfn[MaxN], Low[MaxN], Vis[MaxN], Stack[MaxN], To[MaxN];
inline int read()
{
register int x = 0;
register char ch = getchar();
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x;
}
void Tarjan(int x)
{
Dfn[x] = Low[x] = ++Index;
Stack[++Tail] = x;
Vis[x] = 1;
int to = To[x];
if(!Dfn[to])
{
Tarjan(to);
Low[x] = std::min(Low[x], Low[to]);
}
else if(Vis[x]) Low[x] = std::min(Low[x], Dfn[to]);
if(Dfn[x] == Low[x])
{
int t, res = 0;
do
{
t = Stack[Tail--];
Vis[t] = 0;
++res;
}
while(t != x);
if(res > 1 && res < Ans) Ans = res;
}
}
int main()
{
N = read();
for(int i = 1; i <= N; ++i) To[i] = read();
for(int i = 1; i <= N; ++i)
if(!Dfn[i]) Tarjan(i);
printf("%d\n", Ans);
return 0;
}