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

      

  • 相关阅读:
    git 命令速查及使用
    Centos6.5 LAMP环境源码包安装与配置,附安装包百度网盘地址 (转做笔记)
    不再为Apache进程淤积、耗尽内存而困扰((转))
    centos6.5 安装linux 环境
    window 配置wnmp(转下整理 ,全)
    mac下安装 xampp 无法启动apache (转,留用)
    Git命令行(转用于学习和记录)
    apache 局域网访问
    华为云GaussDB(for opengauss)如何绑定公网,实现putty的远程访问gaussdb数据库。
    Day9 打卡acwing.429 奖学金
  • 原文地址:https://www.cnblogs.com/ZiningTang/p/3845083.html
Copyright © 2011-2022 走看看