小希的迷宫(并查集)
坑爹啊。。。 这道题不难但是还是wa了四次,首先该图必须连通的**,其次房间号码大小不一定从1开始,所以他的大小可以随意的,在初始化的时候需要将持续到MAXN,当直接输入0 0的时候输出的是YES,还有就是虽然集合合并后,但是father还不一定相同,必须Find后才能相同
#include<stdio.h> const int MAXN=100010; int father[MAXN],rank[MAXN]; struct Node { int x,y; } node[MAXN]; void Make_set() { for(int i=1;i<=MAXN;i++) { rank[i]=0; father[i]=i; } } int Find(int x) { int r=x; while(r!=father[r]) { r=father[r]; } if(r!=x) father[x]=r; return father[x]; } void Union(int x,int y) { //秩小的加到大的里 if(rank[x]>rank[y]) { father[y]=x; } else { if(rank[x]==rank[y]) { rank[y]++; } //rank[x]<rank[y],也是father[x]=y,所以省略 father[x]=y; } } int main() { int cas,flag,i; while(1) { cas=flag=0; while(scanf("%d%d",&node[cas].x,&node[cas].y)) { if(node[cas].x==-1 && node[cas].y==-1) return 0; if(node[cas].x==0 && node[cas].y==0) break; cas++; } Make_set(); for(i=0;i<cas;i++) { int x=Find(node[i].x); int y=Find(node[i].y); if(x==y) { flag=1; } else Union(x,y); } int temp=Find(node[0].x); /*for(i=0;i<cas;i++) { printf("%d %d\n",father[node[i].x],father[node[i].y]); } for(i=0;i<cas;i++) { printf("%d %d\n",Find(node[i].x),Find(node[i].y)); }*/ for(i=0;i<cas;i++) { if(Find(node[i].x)!=temp) flag=1; if(Find(node[i].y)!=temp) flag=1; } if(flag) printf("No\n"); else printf("Yes\n"); } return 0; }