小希的迷宫
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 30305 Accepted Submission(s): 9399
Problem Description
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
Input
输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
整个文件以两个-1结尾。
整个文件以两个-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,注意的是,空树也作为一种合法的情况.....wa了好久#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define MAX 100007 using namespace std; int a[MAX],b[MAX]; int used[MAX]; int fa[MAX]; int n,m; void init ( ) { for ( int i = 0 ; i <= 100000 ; i++ ) fa[i] = i; } /*int find ( int x ) { return x==fa[x]?x:fa[x]=find(fa[x]); }*/ int find ( int x ) { int b,tx = x; while ( fa[tx] != tx ) tx = fa[tx]; while ( fa[x] != x ) { b = fa[x]; fa[x] = tx; x = b; } return tx; } void _union ( int x , int y ) { if ( x == y ) return; x = find(x); y = find(y); fa[x] = y; } int main ( ) { while ( ~scanf ( "%d%d" , &a[0] , &b[0] ) ) { if ( a[0] == -1 && b[0] == -1 ) break; if ( a[0] == 0 && b[0] == 0 ) { puts ( "Yes" ); continue; } memset ( used , 0 , sizeof ( used ) ); n = a[0]==b[0]?1:2; m = 1; used[a[0]] = used[b[0]] = 1; init(); _union ( a[0] , b[0] ); while ( ~scanf ( "%d%d" , &a[m] , &b[m] ) , a[m]+b[m] ) { if ( !used[a[m]] ) n++; used[a[m]]++; if ( !used[b[m]] ) n++; used[b[m]]++; _union ( a[m] , b[m] ); m++; } if ( n != m+1 ) { puts ( "No" ); continue; } int root = -1; bool flag = true; for ( int i = 1 ; i <= 100000 ; i++ ) if ( used[i] ) if ( root == -1 ) root = find(i); else if ( find(i) != root ) { flag = false; break; } puts ( flag?"Yes":"No"); } }