并查集 hdu-1272 小希的迷宫

题目描述

判断一个无向图是不是树
Alt

Input

输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
整个文件以两个-1结尾。

Output

对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"Yes",否则输出"No"。

sample input
6 8  5 3  5 2  6 4
5 6  0 0

8 1  7 3  6 2  8 9  7 5
7 4  7 8  7 6  0 0

3 8  6 8  6 4
5 3  5 6  5 2  0 0

-1 -1
sample output
Yes
Yes
No

思路

判断一棵树,无向图,注意以下几点就好:
1、只有一个根
2、当一个数作为另一个数的子结点时,他们没有相同的父结点

代码里也对思路有注释

#include<bits/stdc++.h>
using namespace std;

int f[100010];       //记录父结点
bool v[100010];        //标记,待会用来数根的

int find(int x) {        //路径压缩
	return x==f[x]?x:f[x]=find(f[x]);
}

void unions(int x, int y) {
	int fx=find(x);
	int fy=find(y);
	if ( fx!=fy ) f[fx]=fy;
}

int main() {
	int x,y;
	while(1) {
		int x,y;
		bool flag=1;
		for(int i=1; i<=100000; i++ ) {
			f[i]=i,v[i]=0;
		}
		while(~scanf("%d %d",&x,&y)) {
			if ( x==-1 && y==-1 ) return 0;
			if ( x==0 && y==0 ) break;
			if ( flag==0 ) continue;
			if ( find(x)==find(y) && x!=y ) {       //这里就是注意点2
				flag=0;continue;
			}
			unions(x,y);
			v[x]=v[y]=1;
		}
		int root=0;
		for(int i=1; i<=100000; i++ ) {         //注意点1,判断根数
			if ( v[i] && i==find(i) ) root++;
			if ( root>1 ) flag=0;
		}
		if ( flag ) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}
发布了13 篇原创文章 · 获赞 6 · 访问量 581

猜你喜欢

转载自blog.csdn.net/zx1020354953/article/details/104103668