hdu 3038

来源:互联网 发布:有意识的人工智能 编辑:程序博客网 时间:2024/06/06 18:26

一道并查集,有对于我比较复杂的地方。看了他们的题解强行理解。利用并查集,用sum【集合的尾数】保存集合的和,合并的时候选小的(左)为父节点。这样遇到边界一样的集合,就可以判断是否冲突。

#include<cstdio>const int maxn = 200000 + 5;int sum[maxn];int pre[maxn], ans;void init(int n){    for(int i = 0; i <= n; i++)    {        sum[i] = 0;        pre[i] = i;    }    ans = 0;}int root(int x){    if(x == pre[x])        return x;    int t = pre[x];    pre[x] = root(pre[x]);    sum[x] += sum[t];    return pre[x];}void merge_set(int s, int e, int v){    int fx = root(s);    int fy = root(e);    if(fx == fy)    {        if(sum[e] != sum[s] + v)            ans++;        return;    }    else if(fx > fy)    {        sum[fx] = sum[e] - v - sum[s];        pre[fx] = fy;    }    else    {        sum[fy] = sum[s] + v - sum[e];        pre[fy] = fx;    }}int main(){    int n, m;    while(scanf("%d%d", &n, &m) == 2)    {        init(n);        for(int kase = 1; kase <= m; kase++)        {            int t1, t2, t3;            scanf("%d%d%d", &t1,&t2, &t3);            merge_set(t1 - 1, t2, t3);        }        printf("%d\n", ans);    }    return 0;}


原创粉丝点击