并查集的运用(例题hdu1272)

题意:给你一个图,判断任意两个点之间是否只能有一条路能够到达。
思路:对于输入的两个点,如果已经输入过了,判断所在集合根节点是否相同,相同则输出No,否则尽量将所有节点合并到一个集合里面,最后只剩下一个集合,也就是说只有一个根节点了,这时需要遍历输入的数据判断father[i]=i个数,如果个数大于1个输出No。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int f[110000],book[110000],flag;
int find(int u)
{
	if (f[u]!=u)
		f[u]=find(f[u]);
	return f[u];

}
void merge(int x,int y)
{
	int t1=find(x),t2=find(y);
	if (t1!=t2)
		f[t2]=t1;
	else
		flag++;
}
int main()
{
	int a,b,i,j;
	while(~scanf("%d%d",&a,&b))
	{

		flag=0;
		if (a==-1&&b==-1)
			break;
		for (i=0; i<=110000; i++)
			f[i]=i;
		memset(book,0,sizeof(book));
		book[a]=1,book[b]=1;
		merge(a,b);
		if (a==0&&b==0)
		{
			printf("Yes\n");
			continue;
		}
		while(~scanf("%d%d",&a,&b))
		{
			if (a==0&&b==0)
				break;
			book[a]=1,book[b]=1;
			merge(a,b);
		}
		int s=0;
		for (i=0; i<=110000; i++)
		{
			if (book[i]&&f[i]==i)
				s++;
		}
		if (flag)
		{
			printf("No\n");
		}
		else
		{
			if (s==1)
				printf("Yes\n");
			else
				printf("No\n");
		}
	}
	return 0;
}
posted @ 2020-09-27 11:07  索饮  阅读(144)  评论(0编辑  收藏  举报