题目的描述就不复制了
【题目分析】
只有n条边的图,一定是有环的,所以一定有强连通分量,每一个强连通分量的节点数就是最小的轮数。用来练习写tarjan了
【代码】
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <stack>
#define M(a) memset(a,-1,sizeof a)
using namespace std;
int h[200001],ne[200001],u[200001],v[200001],en=0;
int dfn[200001],low[200001],nu=0,ans=0x3f3f3f3f;
int vis[200001],in[200001];
const int inf=0x3f3f3f3f;
stack <int> q;
inline void add(int a,int b)
{
u[en]=a;v[en]=b;
ne[en]=h[a];
h[a]=en++;
}
inline void tarjan(int u)
{
vis[u]=1;
dfn[u]=low[u]=++nu;
in[u]=1;
q.push(u);
for (int i=h[u];i>=0;i=ne[i])
if (!vis[v[i]]) tarjan(v[i]),low[u]=min(low[u],low[v[i]]);
else if (in[v[i]])low[u]=min(low[u],dfn[v[i]]);
if (dfn[u]==low[u])
{
int now=0;
while (1)
{
int x;
x=q.top();
q.pop();
now++;
in[x]=0;
if (x==u)break;
}
ans=min(ans,now>1?now:inf);
}
}
int main()
{
M(h);M(ne);M(u);M(v);
int n;
scanf("%d",&n);
for (int i=1;i<=n;++i)
{
int x;
scanf("%d",&x);
add(i,x);
}
for (int i=1;i<=n;++i)
{
if (!vis[i]) tarjan(i);
}
printf("%d\n",ans);
}