HDU 1272 小希的迷宫
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1272
思路:并查集的运用
当用find函数去查找祖先时,如果合并过程中查找到的祖先相同,那么说明有两条路可以连通,就不符合要求
1 #include<string.h> 2 #include<stdio.h> 3 int f[100010];//存放一个节点的父节点的编号 4 bool is[100010];//标志编号为I的房间是否存在 5 void exist(int x,int y)//判断x,y点是否已经存在 6 { 7 if(!is[x]){ 8 is[x]=1; 9 f[0]++;//统计房间个数 10 } 11 if(!is[y]){ 12 is[y]=1; 13 f[0]++; 14 } 15 } 16 int find(int x) 17 { 18 while(f[x]) x=f[x]; 19 return x; 20 } 21 int merge(int x,int y) 22 { 23 int fx=find(x); 24 int fy=find(y); 25 if(fx!=fy){ 26 f[fx]=fy; 27 f[0]--;//这里f[0]--可用来得到最后树的个数,即总的房间数减去合并的个数 28 } 29 else is[0]=1;//一经发现有重复现象,立即置一,不再往下进行 30 } 31 int main() 32 { 33 int x,y; 34 while(scanf("%d%d",&x,&y),~x||~y) 35 { 36 if(!(x||y)){ //特殊情况啊,为此我贡献了一个WA 37 puts("Yes"); 38 continue; 39 } 40 memset(f,0,sizeof(f));//这里我是让假如一个节点的父节点为0,则此节点为祖先节点 41 memset(is,0,sizeof(is)); 42 merge(x,y); 43 exist(x,y); 44 while(scanf("%d%d",&x,&y),x||y) 45 if(!is[0]){ 46 merge(x,y); 47 exist(x,y); 48 } 49 if(f[0]==1&&!is[0]) puts("Yes");//2个判定条件,树只有一个且没有重复路 50 else puts("No"); 51 } 52 return 0; 53 }