zoukankan      html  css  js  c++  java
  • hdu 1829-A Bug's LIfe(简单带权并查集)

    题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b。只需要判断有没有,按题目要求输出。这题有点坑的地方在于输出上多了一行空行,不PE都没注意到。

    思路:

      用一个数组gender[i] 记录当前节点 i 与根节点的关系,parent[i]数组记录当前节点的父节点。 因为是带权并查集,在Find_Parent 时更新当前节点与根节点的关系,且路径压缩至根节点下, 所以不用像普通并查集一样开辟辅助路径压缩的数组,合并的时候不用路径压缩。

      由于只有同性、异性两种关系,所以用gender[]数组存0、1表示两种性别。根节点相同的且性别相同的则是同性恋。

      然后下面说说不好理解的 Find_parent和合并时 对gender[] 的更新。

      首先,初始化的时候所有节点的父节点都是自己,gender[]都为0。又因为合并时无需路径压缩,所以根节点的gender始终为0,这是推导其他子节点关系的关键。

      Find_parent:由根节点始终为0,我们可以得到在Find_Parent时当前节点 i 与根节点的更新公式:gender[i] = gender[i] ^ gender[ par[i] ] (^为异或). 即 i 和 par[i] 性别相同 则 i 和根节点是异性,否则 i 和根节点则为同性。

      合并操作:合并x, y,找到x, y的父节点a, b,合并par[a] = b, 作为 子节点的那个父节点对根节点的关系 由gender[x] 和 gender[y]决定, 由于多加了一条边,所以gender[a] = (gender[x] + gender[y] +1)%2.

      判断同性恋:Union()返回布尔值,如果x, y父节点相同且性别相同则直接返回true表示找到同性恋,否则返回false。其他合并操作如上。

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 #define maxn 2006
     5 int gen[maxn], par[maxn];
     6 int Find(int x)
     7 {
     8    if(par[x] == x) return x;
     9    int t = Find(par[x]);
    10    gen[x] = gen[x]^gen[par[x]];
    11    return par[x] = t;
    12 }
    13 bool Union(int x, int y)
    14 {
    15    int a = Find(x);
    16    int b = Find(y);
    17    if(a == b){
    18       if(gen[x] == gen[y]) return true;
    19       return false;
    20    }
    21    par[a] = b;
    22    gen[a] = (gen[x]+gen[y]+1)%2;
    23    return false;
    24 }
    25 
    26 int main()
    27 {
    28    int t; cin>>t;
    29    for(int z = 1; z <= t; z++){
    30       int flag = 0;
    31       int n, m; scanf("%d%d", &n, &m);
    32       for(int i = 1; i <= n; i++) par[i] = i, gen[i] = 0;
    33 
    34       for(int i = 0; i < m; i++){
    35          int a, b;  scanf("%d%d", &a, &b);
    36          if(flag) continue;
    37          flag = Union(a, b);
    38       }
    39 
    40       if(flag)
    41          printf("Scenario #%d:
    Suspicious bugs found!
    
    ", z);
    42       else printf("Scenario #%d:
    No suspicious bugs found!
    
    ", z);
    43    }
    44 }
    View Code

      

  • 相关阅读:
    C#磁吸屏幕窗体类库
    准备
    我写的诗
    How to turn off a laptop keyboard
    How to tell which commit a tag points to in Git?
    Why should I care about lightweight vs. annotated tags?
    How to get rid of “would clobber existing tag”
    Facebook, Google and Twitter threaten to leave Hong Kong over privacy law changes
    The need for legislative reform on secrecy orders
    Can a foreign key be NULL and/or duplicate?
  • 原文地址:https://www.cnblogs.com/ZiningTang/p/3845083.html
Copyright © 2011-2022 走看看