中文题,就不说题意了,都能看懂。
大致思路:这个题是一个并查集题加最小生成树,就是判断路径中是否有多余的边,有就输出NO,没有YES
输入数据的时候需要注意,还有数据比较大,开数组注意
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
整个文件以两个-1结尾。
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
Yes Yes No
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int n,m,w,i,j; int f[100002],sum,cot,e[100002],book[100002]; void init() { for(i=1; i<100005; i++) { f[i]=i; book[i]=0; } } int getf(int v) { if(f[v]==v)return v; else { f[v]=getf(f[v]); return f[v]; } } void merge(int v,int u) { int t1,t2; t1=getf(v); t2=getf(u); if(t1!=t2) f[t2]=t1; else w=0; //w=0说明有重复的点出现,此时就不用往下判断了,直接 输出NO book[v]=1; book[u]=1; } int main() { while(~scanf("%d%d",&n,&m)) { if(n==-1&&m==-1)break; if(n==0&&m==0) { printf("Yes\n"); continue; } init(); //初始化f数组 w=1; sum=0; merge(n,m); while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; merge(n,m); } if(w==0) { printf("No\n"); continue; } for(i=1; i<100005; i++) if(f[i]==i&&book[i])sum++; //如果有共同的祖先,说明没有多余的路 if(sum==1)printf("Yes\n"); else printf("No\n"); } return 0; }