hdu6109 数据分割(并查集+set)

题目:hdu6109
思路:每输入一行合并一下,如何产生矛盾则说明该行为后为分隔符。
合并用并查集,同时还需要一个维护一个set来存储不等条件之间的关系。
利用两个数组flag 和flag2来作为并查集和set的“脏位”。
代码如下:

#include <cstdio>
#include <algorithm>
#include <set>

using namespace std;


const int maxn = (int)1e5 + 10;
int flag[maxn], flag2[maxn];
int fa[maxn];
int cnt, ans[maxn], indx;
set<int> S[maxn];
set<int> :: iterator it;


int find(int x) {
    if (flag[x] != indx) {
    flag[x] = indx;
    fa[x] = x;
    }
    return fa[x] != x ? fa[x] = find(fa[x]) : x;

}

bool unit(int r1, int r2) {
    if (S[r1].size() < S[r2].size())
    swap(r1, r2);
    if (r1 == r2) return true;
    for (it = S[r2].begin(); it != S[r2].end(); it ++) {
    if (find(*it) == r1) return false;
    S[r1].insert(find(*it));
    }
    fa[r2] = r1;
    return true;

}

int main(){
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);

    indx ++;
    int L; scanf("%d", &L);

    while (L--) {
    int u, v, e;
    scanf("%d %d %d", &u, &v, &e);

    ans[cnt] ++;

    int r1 = find(u), r2 = find(v);

    if (flag2[r1] != indx) {
        flag2[r1] = indx;
        S[r1].clear();
    }

    if (flag2[r2] != indx) {
        flag2[r2] = indx;
        S[r2].clear();
    }

    if (e) {
        if (!unit(r1, r2)) { indx ++; cnt ++;}

    }
    else {
        if (r1 == r2) {indx ++; cnt ++;}
        else {
        S[r1].insert(r2);
        S[r2].insert(r1);
        }
    }



    }
    printf("%d\n", cnt);
    for (int i = 0; i < cnt; i ++) printf("%d\n", ans[i]);


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值