hdu 1232 畅通工程【并查集】【模板题】

hdu 1232 畅通工程 

hdu 1232 畅通工程【并查集】【模板题】_第1张图片

#include
#include
using namespace std;
int pre[1005];
int find (int x)
{
	int r=x;
	while(pre[r]!=r)
	r=pre[r];
	
	int i=x;
	int j;
	while(i!=r)
	{
		j=pre[i];
		pre[i]=r;
		i=j;
	}
	return r;
}
void join (int x,int y)
{
	int fx=find(x);   //选择根节点
	int fy=find(y);
	if (fx!=fy)
	{
		pre[fx]=fy;
	}
}

int main()
{
	int N,M,a,b,i;
	while(cin>>N>>M && N)
	{
		for(i=1;i<=N;i++)//初始化pre[] 
		{
			pre[i]=i;//每个城市都是独立的。把=写成了==,找了好久的bug 
		}
		
		for(i=1;i<=M;i++)
		{
			cin>>a>>b;
			join(a,b);
		}
		
		int ans=0;
		for(i=1;i<=N;i++)
		{
			//if(i==find(i))//找到一个根节点,ans++ 
			if(pre[i]==i)
			{
			ans++;
			}	
		}
//		for(int i=1;i<=N;++i)   //【测试】依次输出1~n的根节点 
//		 	cout<

 

//另开一个数组t[],存是不是根节点
#include
#include
using namespace std;
int pre[1005];
int find(int x)
{
	int r=x;
	while(r!=pre[r])   //寻找根节点,(pre[r]是 r 的 上级,) 
	r=pre[r];
	int i=x,j;
	while(i!=r)        //压缩路径,使得每一个子节点的上级直接为根节点,省去层层回溯 
	{ 
	    j=pre[i];
		pre[i]=r;
		i=j;
	}
	return r;
}
 
void join(int a,int b)
{ 
	int fx=find(a);   //选择根节点
	int fy=find(b);   //选择根节点 
	if(fx!=fy)        //若相等,即为同一根节点,否则,用跟节点进行合并  
	{
		pre[fx]=fy;   //根节点合并  
	}
} 
 
int main()
{
	int n,m;
	while(cin>>n>>m&&n)
	{
		
		bool t[1005];          //用来做最终统计 
		int ans=-1;
		memset(t,0,sizeof(t));
		
		for(int i=1;i<=n;++i)
		pre[i]=i;              //初始化 
		
		int a,b;
		for(int i=1;i<=m;++i)
		{
			cin>>a>>b;
			join(a,b);          //合并操作 
		}
		
		for(int i=1;i<=n;++i)//i是根节点,t[i]=1 
		    t[(find(i))]=1;	  
		    
		
		for(int i=1;i<=n;++i)//统计根节点个数 
		    if(t[i])
			ans++; 
//		for(int i=1;i<=n;++i)   //【测试】依次输出1~n的根节点 
//		 	cout<

 

你可能感兴趣的:(并查集)