-
题目
-
题意
乍一看,是个并查集的题目啊。然后,不知道怎么思考了。
这题,其实没有必要按照题目的顺序走,没有必要第一轮怎么怎么样,第二轮又怎么怎么样。
因为,每一轮只会在并查集上增加一条边,所以,只要再次出现了pre[ i ] = i 的情况时,数一数这个并查集有几条边,就是进行了几轮传递。
最后,由于可能会产生不止一个并查集,所以需要遍历所有的点。
-
代码
//P2661
#include<iostream>
#include<algorithm>
#include<set>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#include<stdio.h>
#include<map>
using namespace std;
#define ll long long
const int maxn=200005;
int n;
int ans=maxn;
int cnt=0;
int num[maxn];
int pre[maxn];
void Init()
{
for(int i=1;i<=n;i++)
pre[i]=i;
}
int find(int x)
{
cnt++;
if(pre[x]==x) return x;
else
return find(pre[x]);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
Init();
for(int i=1;i<=n;i++)
{
cnt=0;
if(find(num[i])==i)
ans=min(ans,cnt);
else
pre[i]=num[i];
}
cout<<ans<<endl;
}