[Noip2015]信息传递

[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;
} 
原文地址:https://www.cnblogs.com/clockwhite/p/13510257.html