首页 > 代码库 > hdu1272 小希的迷宫 基础并查集

hdu1272 小希的迷宫 基础并查集

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int M = 100005;
 8 int a, b;
 9 int father[M];       //记录父节点 
10 bool circle;         //判断是否存在环 
11 bool visit[M];       //用来记录顶点数  
12 int edgenum, vnum;    //分别表示边数,顶点数 
13 
14 void initial()
15 {
16     for (int i = 0; i<M; i++)
17         father[i] = i, visit[i] = false;
18     circle = false;
19     edgenum = vnum = 0;
20 }
21 
22 //(查)
23 int find(int x)
24 {
25     return x == father[x] ? x : father[x] = find(father[x]);     //找祖先节点 + 路径压缩 
26 }
27 
28 //(并)
29 void merge(int a, int b)
30 {
31     if (a == b)
32         circle = true;
33     int x, y;
34     x = find(a);
35     y = find(b);
36     if (x != y)
37     {
38         father[x] = y;
39         edgenum++;       //引出一条边 
40     }
41     else
42         circle = true;   //x==y,说明他们是同一个祖先,一旦连通便与祖先3者成环 
43 }
44 
45 int main()
46 {
47     while (true)
48     {
49         initial();
50         scanf("%d%d", &a, &b);
51         if (a == 0 && b == 0)
52         {     //为空树 
53             printf("Yes\n");
54             continue;
55         }
56         if (a == -1 && b == -1)
57             break;
58         visit[a] = true;
59         visit[b] = true;
60         merge(a, b);
61         while (true)
62         {
63             scanf("%d%d", &a, &b);
64             if (a == 0 && b == 0)
65                 break;
66             visit[a] = true;
67             visit[b] = true;
68             merge(a, b);
69         }
70         for (int i = 0; i < M; i++)
71         {
72             if (visit[i])
73                 vnum++;
74         }
75         if (!circle && edgenum + 1 == vnum)
76             printf("Yes\n");
77         else
78             printf("No\n");
79     }
80     return 0;
81 }

 

hdu1272 小希的迷宫 基础并查集