HDU-1829 A Bug's Life (种类并查集)

题意:已知某昆虫有雄雌两性,然后给出案例数t, 对应每一个案例中给出编号数目和关系数目n,m ,在接下来m行中给出对应关系为异性的a b,最后判断所给中关系中是否有冲突部分

思路:关于种类并查集,有两种思路

(1) 开对应集合数量倍空间,类似POJ-1703也是两个互斥关系的集合:

有n个成员,开两倍空间(即假设某个成员有两面的属性),1~n为一组, n+1~2n为一组。a与b互斥,则a与b反(即b+n)为同一集合,同时b与a反(a+n)为同一集合,这样就确立联系.同时在union操作中,我们引入rank(相当于模拟某个作为根的结点“高度”,高度越高意味着他作为根连接的其他结点越多,用于在合并的时候进行确立结点连接关系

(2)通过在压缩路径中确立之间的关系,即在Unoin和find中要增加  关系式的转换 也可以参考POJ-1182 食物链(三种集合关系),大部分题解是通过路径压缩关系式确立之间的关系.

这里我采用第一种,思路上比较简单。其中判断是否冲突是通过在每一次条件确立中,如果关系已知,且与当前输入的关系矛盾,则设标志变量flag 为false即关系冲突

然后注意输出格式要多输出一行空白

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 const int maxn = 1e5+7;
 6 using namespace std;
 7 
 8 int pre[2*maxn];
 9 int rank[2*maxn];
10 int find(int x)
11 {
12     if (x == pre[x]) return x;
13     else return pre[x] = find(pre[x]);
14 }
15 
16 void unite(int x, int y)
17 {
18     int px = find(x), py = find(y);
19     if (px == py) return ;
20     else if (rank[px] > rank[py])
21     {
22         pre[py] = px;
23     }
24     else
25     {
26         pre[px] = py;
27         if (rank[px] == rank[py]) rank[py]++;
28     }
29 }
30 
31 bool same(int x, int y)
32 {
33     int px = find(x), py = find(y);
34     return px == py;
35 }
36 int main()
37 {
38     int T, n, m,cnt;
39     scanf("%d", &T);
40     cnt= 0;
41     while(T--)
42     {
43         bool flag = true;
44         scanf("%d%d", &n, &m);
45         for (int i = 1;i <= 2*n; i++)
46         {
47             pre[i] = i;
48             rank[i] = 1;
49         }
50         int a, b;
51         for (int i = 0; i < m; i++)
52         {
53             scanf("%d%d", &a, &b);
54             //以确定关系 
55             if ( same(a, b) || same(a, b+n) )
56             {
57                 if ( same(a, b) ) flag = false;
58                 //是异性则符合条件继续 
59                 else continue;
60             }
61             //未确定关系 
62             else
63                {
64                 unite(a, b+n);
65                 unite(a+n, b);
66             } 
67         }
68         printf("Scenario #%d:
",++cnt);
69         if(!flag) printf("Suspicious bugs found!

");
70         else printf("No suspicious bugs found!

");
71     }
72     return 0;
73 }
原文地址:https://www.cnblogs.com/Tianwell/p/11181057.html