Loading

小希的迷宫 HDU - 1272 (并查集)

 

思路: 当图中的集合(连通子图)个数为1并且边数等于顶点数-1(即改图恰好为一棵生成树)时,输出Yes.

此题的坑:(1) 如果只输入0 0算作一组数据的话答案应该输出Yes

     (2) 输入数据可能并不是连通图,有可能一开始不连通,所以最后一定要判断其连通子图个数是不是1

 

 1 #include<iostream>
 2 #include<vector>
 3 #include<string>
 4 #include<cmath>
 5 #include<set>
 6 #include<algorithm>
 7 #include<cstdio>
 8 #include<map>
 9 #include<cstring>
10 
11 using namespace std;
12 
13 // 小希的迷宫 HDU - 1272
14 
15 /**
16 思路: 当图中的集合(连通子图)个数为1并且边数等于顶点数-1(即改图恰好为一棵生成树)时,输出Yes.
17 此题的坑:(1) 如果只输入0 0算作一组数据的话答案应该输出Yes
18      (2) 输入数据可能并不是连通图,有可能一开始不连通,所以最后一定要判断其连通子图个数是不是1
19 */
20 
21 int Tree[100100];
22 
23 int findRoot(int x)
24 {
25     if(Tree[x] == -1)
26         return x;
27     
28     // 路径压缩
29     int tmp = findRoot(Tree[x]);
30     Tree[x] = tmp;
31     return tmp;
32 }
33 
34 int main()
35 {
36     int a, b;
37     set<int> Set;    // 使用Set保存图中的所有顶点编号
38     for(int i = 0; i <= 100000; ++i)
39         Tree[i] = -1;
40 
41     int rimCnt = 0;
42     while(cin >> a >> b)
43     {
44         if(a == -1 && b == -1)
45             break;
46 
47         if(a == 0 && b == 0)
48         {
49             if(rimCnt == 0)        // 只有输入一组数据0 0的时候,应该输出Yes
50             {
51                 cout << "Yes" << endl;
52                 continue;
53             }
54             int Vcnt = Set.size();    // 顶点计数
55             int Scnt = 0;            // 图中的连通子图(集合)个数
56             for(set<int>::iterator iter = Set.begin(); iter != Set.end(); ++iter)
57             {
58                 if(Tree[*iter] == -1)
59                 {
60                     Scnt++;
61                 }
62             }
63 
64             // 当图中的集合只有一个并且总边数等于顶点数-1的时候,输出Yes
65             if(Scnt == 1 && rimCnt == Vcnt - 1)
66             {
67                 cout << "Yes" << endl;
68             }
69             else
70             {
71                 cout << "No" << endl;
72             }
73 
74             for(int i = 0; i <= 100000; ++i)
75                 Tree[i] = -1;
76             Set.clear();    // 清空集合
77             rimCnt = 0;     // 边数置零
78             continue;
79         }
80         else
81         {
82             rimCnt++;    // 边计数
83             Set.insert(a);
84             Set.insert(b);
85             int ra = findRoot(a);
86             int rb = findRoot(b);
87             if(ra != rb)
88             {
89                 Tree[ra] = rb;
90             }
91         }
92 
93     }
94 
95     return 0;
96 }

 

posted @ 2019-08-23 09:48  拾月凄辰  阅读(176)  评论(0编辑  收藏  举报