思路:看完题目思考了一会后就想到判环即可,统计记录环的长度。
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 200000+10;
int par[maxn], dis[maxn];
int n, temp, ans = 0x3f3f3f3f;
void init(int n) {
for(int i = 1; i <= n; i++)
par[i] = i;
}
int find_(int x) {
if(x == par[x]) return x;
else {
int last = par[x]; //记录它当前的祖先节点
par[x] = find_(par[x]); //修改祖先节点
dis[x] += dis[last]; //更新路径的长度
return par[x];
}
}
void unite(int a, int b) {
int x = find_(a), y = find_(b);
if(x == y) ans = min(ans, dis[a]+dis[b]+1); //如果发现了环那么更新答案
else {
par[x] = y; //将两个节点连接
dis[a] = dis[b] + 1; //更新长度
}
}
int main() {
ios::sync_with_stdio(false);
cin >> n;
init(n);
for(int i = 1; i <= n; i++) {
cin >> temp;
unite(i, temp);
}
printf("%d\n", ans);
}