hdu 1272 小希的迷宫 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272

      第二条并查集,和畅通工程的解法类似。判断小希的迷宫不符合条件,即有回路。我的做法是,在合并两个集合的时候,当fx = fy,即有共同祖先的时候,说明就有回路。

     这题有三点要注意:1、格式问题。题目说的“每两组数据之间有一个空行。”是会PE的!!实际上输出Yes或No之后加多个\n即可,不需要再画蛇添足再输多一个换行。  2、 当整数对列表只有0 0 时,要输出Yes   3、当不相交的集合个数>=2时,也是不符合条件的,要输出No

     

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 const int maxn = 100000 + 5;
 7 int set[maxn], flag[maxn];
 8 int sign;
 9 
10 int find_set(int x)
11 {
12     while (x != set[x])
13         x = set[x];
14     return x;
15 }
16 
17 void union_set(int x, int y)
18 {
19     int fx = find_set(x);
20  //   printf("fx = %d\n", fx);
21     int fy = find_set(y);
22   //  printf("fy = %d\n", fy);
23     if (fx != fy)
24     {
25         set[fx] = fy;
26    //     printf("set[%d] = %d\n", fx, set[fx]);
27     }
28     else
29         sign = 1;
30 }
31 
32 int main()
33 {
34     int a, b, i, j, cnt;
35     memset(set, 0, sizeof(set));
36     memset(flag, 0, sizeof(flag));
37     i = sign = 0;
38     while (scanf("%d%d", &a, &b) && (a != -1 || b != -1))
39     {
40         if (i == 0 && a == 0 && b == 0)   // i = 0代表列表中的数据是第一组
41         {
42             printf("Yes\n"); 
43         }
44         else if (a != 0 && b != 0)
45         {
46             i++;
47             if (!flag[a] && set[a] != a)    // flag的作用是输入数据时当存在多个相同的数据时,保证只需要存入一次set[a],起到类似监视哨的作用
48             {
49                 set[a] = a;
50                 flag[a] = 1;
51     //          printf("set[%d] = %d\n", a, set[a]);
52             }
53             if (!flag[b] && set[b] != b)
54             {
55                 set[b] = b;
56                 flag[b] = 1;
57     //          printf("set[%d] = %d\n", b, set[b]);
58             }
59             if (a > b)
60                 swap(a, b);     // 保证小的数指向的祖先比它大,其实这个判断不要也行
61
union_set(a, b); // 合并a、b元素,使a、b成为一个集合 62 } 63 else 64 { 65 for (cnt = 0, j = 1; j < maxn; j++) 66 if (set[j] == j) // 统计不相交集合个数 67 cnt++; 68 if (cnt > 1) // 不相交集合个数超过1个 69 sign = 1; 70 if (sign) 71 printf("No\n"); 72 else 73 printf("Yes\n"); 74 memset(set, 0, sizeof(set)); 75 memset(flag, 0, sizeof(flag)); 76 i = sign = 0; 77 } 78 } 79 return 0; 80 }

    

    

    

    

原文地址:https://www.cnblogs.com/windysai/p/3254941.html