Poj2492 带权并查集

题目链接在这里
题目大意
bug分公母,有n个bug,m个描述,每个描述里有x和y,代表这两个bug是一对。问给出m个描述之后会不会有同性恋现象。
解题思路
每个Bug的权值初始时设置成0,权值代表着这个bug和其祖宗的性别差异,如果是1就表示是异性,0代表同性。然后在合并的时候,如果发现它们之前已经合并过了并且它们的权值相加为偶数,则就是同性恋。

代码如下

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#define rep(i, n) for(int i = 0; i < n; ++i)
#define clr(x) memset(x, 0, sizeof(x))
using namespace std;

const int MaxN = 2010;
int n, m;
int par[MaxN], Rank[MaxN];
int T;

void init(){
    for(int i = 0; i < MaxN; ++i){
        par[i] = i;
        Rank[i] = 0;
    }
}

int Find(int x){
    if(x == par[x]) return x;
    int tmp = par[x];
    par[x] = Find(par[x]);
    Rank[x] = (Rank[x] + Rank[tmp]) % 2;
    return par[x];
}

bool unite(int x, int y){
    int fx = Find(x);
    int fy = Find(y);

    if(fx == fy){
        if((Rank[x] + Rank[y]) % 2 == 0)  return false;
        else return true;
    }
    par[fx] = fy;
    Rank[fx] = (1 + Rank[y] - Rank[x]) % 2;
    return true;
}

int main(){
    ios::sync_with_stdio(false);
    cin >> T;
    string co[2] = {
        "No suspicious bugs found!",
        "Suspicious bugs found!"
    };
    rep(tt, T){
        init();
        int flag = 0;
        cin >> n >> m;
        int x, y;
        rep(i, m){
            cin >> x >> y;
            if(!unite(x, y))    flag = 1;
        }

        cout << "Scenario #" << tt + 1 << ":" << endl;
        cout << co[flag] << endl << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值