[Noip2015]信息传递
一.前言
其实没有什么写的打算……题目链接
二.思路
这是并查集做法,我认为这种做法没有任何的扩充意义,仅限于这种极端环境找环,这题的的条件十分有限且极端。
题目求最小环长,具体做法是用边将两个点连入并查集,如果已经在一个集合中就是环。同时追加一个到祖先(链的头)的距离,答案就是距离加一。稍加解释就是每个点只有一出一入,成环就好像画( ho),手玩就好……
三.CODE
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<fstream>
#include<cmath>
#include<vector>
using namespace std;
int read(){
char ch=getchar();
int res=0,f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())res=res*10+(ch-'0');
return res*f;
}
int n,fa[200005],ans=1<<30,dis[200005];
int get(int x){
if(fa[x]==x)return x;
int u=fa[x];
fa[x]=get(u);
dis[x]+=dis[u];
return fa[x];
}
void solve(int x,int y){
int b=get(y);
if(x!=b)fa[x]=b,dis[x]=dis[y]+1;//直接就路径压缩
else ans=min(ans,dis[y]+1);
}
int main(){
n=read();
for(int i=1;i<=n;++i)fa[i]=i;
for(int i=1,x;i<=n;++i){
x=read();
solve(i,x);
}
cout<<ans;
return 0;
}