How Many Answers Are Wrong (带权并查集)

  转载:  https://blog.csdn.net/obsorb_knowledge/article/details/81168166

感觉比向量的好理解。。。

#include<stdio.h>
const int maxn  = 200005;
int f[maxn], val[maxn];
int Find(int x)
{
    int k = f[x];
    if(f[x] != x) {
        f[x] = Find(f[x]);
        val[x] += val[k];
    }
    return f[x];
}
int main(){
    int N, M;
    while(scanf("%d%d", &N, &M) != EOF) {
        int i, u, v, w, ans=0;
        for(i=0; i<=N; i++)
        {
            f[i] = i;
            val[i] = 0;
        }
        while(M--) {
            scanf("%d%d%d", &u, &v, &w);
            u = u-1;                //注意为什么要减一
            int ru = Find(u), rv = Find(v);
            if(ru == rv && w != val[v]-val[u])  // 当有相同的最左端时,直接判断 
                ans++;
            // 当最左端不同时 
            else if(ru < rv)  // 结合上面给出的条件 更新区间[ru,rv]所有数的和   
            {                 // 情况 1 
                f[rv] = ru;
                val[rv] = val[u] - val[v] + w;
            }
            else if(ru > rv)   // 更新 区间 [rv,ru]所有数的和    
            {                  // 情况 2 
                f[ru] = rv;  
                val[ru] = val[v] - val[u] - w;
            }
                
        }
        printf("%d
", ans);
    }
    return 0;
}
View Code