hdu1272小希的迷宫(并查集+判环)

题意:给定两个数,这两个数之间连有一条通路,以0,0作为一组数据的结束,以-1,-1作为整体结束,让你判断是否每两个点之间只有一条通路。

思路:每两个点之间要连通(即有关系),由此想到并查集,利用并查集找祖宗(根节点)的方式合并这些给定的点,而且,要满足只有一条通路,那么这集合中不能出现环,(一旦出现环就意味着出现有两点之间出现了多条通路,自己画画看),可以用一个标记flag来判断是否出现环路(出现环路的话就是找祖宗(根节点)时两个点有同一个祖宗(根节点))。

此题还有一个坑点,如果出现两个或以上集合时,一定有两个点不连通,此时是不满足题意的,可以用一个数组vis标记有那些点出现过,然后看看是否出现过的所有点都只有唯一的祖宗。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=100006;
 6 bool flag;
 7 int f[maxn];
 8 int vis[maxn];
 9 int find(int v)//并查集寻找根节点 
10 {
11     if(f[v]==v)
12     return v;
13     else
14     return find(f[v]);
15 }
16 void merge(int u,int v)//合并 
17 {
18     int t1=find(u);
19     int t2=find(v);
20     if(t1!=t2)//两个点的根节点不同,意味着两点属于不同集合 
21     {
22         f[t2]=t1;
23     }
24     else//如果两个点已经在同一个集合(有同一个根节点),就说明已经有一条路将两点相连,再有就不符合题意了 
25     {
26         flag=false;
27     }
28 }
29 int main()
30 {
31     int x,y;
32     while(~scanf("%d%d",&x,&y))//题目要求多组输入,先输入两个数是为了对应下面的特判 
33     {
34         if(x==0&&y==0)//本题的特判,如果只输入了0,0,也是符合要求的,试出来的... 
35         {
36             printf("Yes\n");
37             continue;//需要继续输入下一组数据 
38         }
39         for(int i=0;i<=maxn;i++)//每次输入新的一组数据时都要初始化 
40         {
41             f[i]=i;//并查集初始化 
42             vis[i]=0;//标记出现过的点 
43         }
44         if(x==-1&&y==-1)//输入-1,-1结束 
45         break;
46         merge(x,y);//合并两个点入一个集合 
47         flag=true;//这是判断是否有环路出现的标志 
48         vis[x]=1;
49         vis[y]=1;//将先输入的两点先标记 
50         while(scanf("%d%d",&x,&y),x,y)
51         {
52             merge(x,y);//合并 
53             vis[x]=1;//标记 
54             vis[y]=1;
55         }
56         if(!flag)
57         {
58             printf("No\n");//有环路,则不符合要求 
59             continue;//继续下一组数据 
60         }
61         else//在没有环路的前提下再判断其他情况 
62         {
63             int cnt=0;//判断有几个集合 
64             for(int i=0;i<=maxn;i++)
65             {
66                 if(vis[i]&&f[i]==i)//在已经(给出)出现的点中有几个根节点是自己就有几个集合 
67                 cnt++;
68             }
69             if(cnt==1)
70             {
71                 printf("Yes\n");//当只有一个集合时,符合题意 
72             }
73             else
74             {
75                 printf("No\n");//否则不符 
76             }
77         }
78     }
79 }

 

posted on 2020-04-11 18:31  轻描淡写ぃ  阅读(166)  评论(0编辑  收藏  举报

导航