假设有一条
x
−
>
y
x->y
x−>y 的有向边,当建立连接时,更新
x
x
x的父节点,同时更新
x
x
x 到父节点的距离
l
e
n
[
x
]
=
l
e
n
[
y
]
+
1
len[x]=len[y]+1
len[x]=len[y]+1
若父节点相同说明存在环,环的大小为
l
e
n
[
x
]
+
l
e
n
[
y
]
+
1
。
len[x]+len[y]+1。
len[x]+len[y]+1。
#include<bits/stdc++.h>
#define LL long long
#define pii pair<LL,LL>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
const LL MOD=1e9+7;
int n,tmp,f[maxn],len[maxn],Min=inf;
int getfind(int x){
if(f[x]!=x){//查找祖先的过程中更新路径
int last=f[x];//记录父节点
f[x]=getfind(f[x]);//更新父节点
len[x]+=len[last];//回溯过程更新路径 +父节点到祖先节点的路径
}return f[x];
}
void Merge(int x,int y){
int k1=getfind(x);
int k2=getfind(y);
if(k1!=k2){
f[k1]=k2;
len[x]=len[y]+1;
}else{
Min=min(Min,len[x]+len[y]+1);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=n;i++){
scanf("%d",&tmp);
Merge(i,tmp);
}
printf("%d\n",Min);
return 0;
}