小希的迷宫 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 int Tree[100100];
14
15 int findRoot(int x)
16 {
17 if(Tree[x] == -1)
18 return x;
19 int tmp = findRoot(Tree[x]);
20 Tree[x] = tmp;
21 return tmp;
22 }
23
24 int main()
25 {
26 int a, b;
27 set<int> Set; // 使用Set保存图中的所有顶点编号
28 for(int i = 0; i <= 100000; ++i)
29 Tree[i] = -1;
30
31 int rimCnt = 0;
32 while(cin >> a >> b)
33 {
34 if(a == -1 && b == -1)
35 break;
36
37 if(a == 0 && b == 0)
38 {
39 if(rimCnt == 0) // 只有输入一组数据0 0的时候,应该输出Yes
40 {
41 cout << "Yes" << endl;
42 continue;
43 }
44 int Vcnt = Set.size(); // 顶点计数
45 int Scnt = 0; // 图中的连通子图(集合)个数
46 for(set<int>::iterator iter = Set.begin(); iter != Set.end(); ++iter)
47 {
48 if(Tree[*iter] == -1)
49 {
50 Scnt++;
51 }
52 }
53
54 // 当图中的集合只有一个并且总边数等于顶点数-1的时候,输出Yes
55 if(Scnt == 1 && rimCnt == Vcnt - 1)
56 {
57 cout << "Yes" << endl;
58 }
59 else
60 {
61 cout << "No" << endl;
62 }
63
64 for(int i = 0; i <= 100000; ++i)
65 Tree[i] = -1;
66 Set.clear(); // 清空集合
67 rimCnt = 0; // 边数置零
68 continue;
69 }
70 else
71 {
72 rimCnt++; // 边计数
73 Set.insert(a);
74 Set.insert(b);
75 int ra = findRoot(a);
76 int rb = findRoot(b);
77 if(ra != rb)
78 {
79 Tree[ra] = rb;
80 }
81 }
82
83 }
84
85 return 0;
86 }