并查集入门--hd 1272 小希的迷宫 并查集判断环

来源:互联网 发布:c语言入门经典程序 编辑:程序博客网 时间:2024/05/18 22:43

小希的迷宫

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 54463    Accepted Submission(s): 17097


Problem Description
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。

 

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

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

Sample Input
6 8 5 3 5 2 6 45 6 0 08 1 7 3 6 2 8 9 7 57 4 7 8 7 6 0 03 8 6 8 6 45 3 5 6 5 2 0 0-1 -1
 
Sample Output
YesYesNo


做这道题的时候总是思路不到位,原因是不知道成环的条件 ,成环的条件是: 在输入时 输入两个地方表示这两个地方连通,如果说这两个地方的父节点都相同,则做个图都知道这两个点连到同一个父节点,并且这两个点也相连,那不表示成环了吗,因此在并查集里面放入一个判断成环的bool变量circle,以及确定(edgnum 边数是否等于其顶点数-1 【这里不懂可以看我上个并查集的题解】)(如果相等就说明没有成环)输出yes  否则输出no
so good!


#include <iostream>#include <algorithm>using namespace std;const int M = 100005;int a,b;int father[M];       //记录父节点 bool circle;         //判断是否存在环 bool visit[M];       //用来记录顶点数  int edgenum,vnum;    //分别表示边数,顶点数 void initial( ){     for( int i=0 ; i<M ; i++ )          father[i] = i,visit[i]=false;     circle = false;       edgenum = vnum = 0;      }int find(  int x ){    return x == father[x] ? x : father[x] = find(father[x]);     //找祖先节点 + 路径压缩 }void merge( int a ,int b ){     if( a == b )         circle = true;     int x , y;     x = find(a);     y = find(b);     if( x != y ){         father[x] = y;         edgenum++;       //引出一条边      }     else         circle = true;   //x==y,说明他们是同一个祖先,一旦连通便与祖先3者成环 }int main(){    while( true ){           initial( );           scanf("%d%d",&a,&b);           if( a==0 && b==0 ){     //为空树                printf("Yes\n");                      continue;           }           if( a==-1 && b==-1 )               break;           visit[a] = true;           visit[b] = true;           merge( a,b );           while( true ){                  scanf("%d%d",&a,&b);                  if( a==0 && b==0 )                      break;                  visit[a] = true;                  visit[b] = true;                  merge( a , b );                 }           for( int i=0 ; i<M ; i++ )                if( visit[i] )                    vnum++;   //判断顶点数           if(  !circle && edgenum+1 == vnum )               printf("Yes\n");           else               printf("No\n");    }         return 0;}







Sample Output
YesYesNo
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鱼缸过滤效果不好怎么办? 煮水壶有水垢怎么办 猫咪喝了咖啡怎么办 军用水壶凹了怎么办 新电水壶有味道怎么办 猫夏天不喝水怎么办 军用水壶瘪了怎么办 木头壶盖有异味怎么办 挎包拉链坏了怎么办 斜挎包没有拉链怎么办 树脂补牙没抛光怎么办 猪拉稀不吃食怎么办 亚麻衣服刺皮肤怎么办 自热米饭不熟怎么办 孕妇用了微波炉怎么办 蛋挞变软了怎么办 外卖炒面坨了怎么办 手机发热充电慢怎么办 饭盒盖子松了怎么办 饭盒盖子盖不住怎么办 饭盒盖子吸不住怎么办 饭盒盖子变形了怎么办 饭盒盖子凹进去怎么办 饭盒盖吸不住怎么办 饭盒微波炉加热后打不开怎么办 微波炉加热饭盒打不开怎么办 塑料饭盒加热后打不开怎么办 真空锅锅盖打不开怎么办 玻璃真空水壶打不开怎么办 保温饭盒盖子打不开怎么办 饭盒盖章松了怎么办 电压力锅卡住了怎么办 铁的饭盒打不开怎么办 微波炉饭盒盖子打不开怎么办 微波炉盖子吸住了怎么办 剩下的糯米饭怎么办 饭盒微波加热打不开怎么办 微波炉触屏不灵怎么办 微波炉旋钮坏了怎么办 微波炉蒸馒头硬怎么办 小猫两天不吃饭怎么办