HDU-1272-小希的迷宫

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1272

 

/*
程序分析:
    题目意思其实就是让你判断一个图是不是一棵树,条件就是无环、连通图,即连通分支为一
解决方法:
    利用并查集,把输入的房间视为一个点,有路径的就连成一起,只要找到了环,就可以判定为NO了,
如果到输入最后都还没找到环就只剩两种可能了,一种就是只有一棵书,一种就是有一个以上的树,这样也可以判定是否符合问题要求了。
*/


 

 

View Code
 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int Max = 100000+10;
 5 int Far[Max];
 6 int Rank[Max];
 7 int Sign[Max];
 8 
 9 void Make_set(int n)
10 {
11     int i;
12     for(i=0; i<=n; i++)
13     {
14         Far[i] = i;
15     }
16     memset(Rank, 0, sizeof(Rank));
17     memset(Sign, 0, sizeof(Sign));
18 }
19 
20 int Find_set(int x)
21 {
22     if(Far[x] != x)
23         return Far[x] = Find_set(Far[x]);
24     return Far[x];
25 }
26 
27 void Unio(int a, int b)
28 {
29     a = Find_set(a);
30     b = Find_set(b);
31     if(a == b)
32         return;
33     if(Rank[a] < Rank[b])
34         Far[a] = b;
35     else if(Rank[a] > Rank[b])
36         Far[b] = a;
37     else 
38     {
39         Far[a] = b;
40         Rank[b]++;
41     }
42 }
43 
44 int main()
45 {
46     int a, b;
47     //初始化
48     int flag = 1;
49     Make_set(Max);
50     while(cin>>a>>b && a!=-1 && b!=-1)
51     {
52         if(a == 0  && b == 0) //待一组数据输入完毕后才输出结果
53         {
54             int ans = 0;
55             for(int i=1; i<=Max; i++)
56             {
57                 if(Sign[i] && Find_set(i) == i)  //统计有几个连通分支
58                     ans++;
59             }
60             if(ans > 1)  //连通分支大于1,表示还有有个别房间不能连通
61                 flag = 0;
62             if(flag)
63                 cout<<"Yes"<<endl;
64             else
65                 cout<<"No"<<endl;
66             //从新初始化
67             flag = 1; //表示为Yes
68             Make_set(Max);
69             continue;
70         }
71         if(a != b && Find_set(a) == Find_set(b))  //根节点相同,但叶子不同,表示a,b已存在路径,如果
72         {                                          //仍增加一条路径则会存在环,则有第二天路径
73             //cout<<"No"<<endl;
74             flag  = 0;
75         }
76         else
77         {
78             Sign[a] = 1;
79             Sign[b] = 1;
80             Unio(a, b);
81         }
82     }
83     return 0;
84 }

 

 

View Code
 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 bool used[100001];
 5 int r[100001];
 6 int find(int x)
 7 {
 8     while(r[x]!=x)
 9         x=r[x];
10     return x;
11 }
12 int uni(int x,int y)
13 {
14     x=find(x);
15     y=find(y);
16     if(x=y)return 0;
17     r[x]=y;
18     return 1;
19 }
20 int main()
21 {
22     int n,m,flag,i,t;
23     while(cin>>n>>m)
24     {
25         if(n==-1&&m==-1)return 0;
26         if(n==0&&m==0)
27         {
28             cout<<"Yes\n";
29             continue;
30         }
31         memset(used,0,sizeof(used));
32         for(i=0;i<100001;i++)
33         {
34             r[i];
35         }
36         uni(n,m);
37         used[n]=used[m]=1;t=1;
38         flag=1;
39         while(cin>>n>>m)
40         {
41             if(n==0&&m==0)break;
42             if(used[n]==0){t++;used[n]=1;}
43             if(used[m]==0){t++;used[m]=1;}
44             if(uni(n,m)==0)flag=0;
45             else t--;
46         }
47         if(flag&&t==1)cout<<"Yes\n";
48         else cout<<"No\n";
49     }
50     return 0;
51 
52 }

 

 

posted @ 2012-08-25 19:05  另Ⅰ中Feel▂  阅读(154)  评论(0编辑  收藏  举报