1. 程式人生 > >BZOJ1202 狡猾的商人 叒是並查集

BZOJ1202 狡猾的商人 叒是並查集

「BZOJ1202」 [HNOI2005]狡猾的商人

「BZOJ1202」 [HNOI2005]狡猾的商人の傳送門

利用字首和
(x - 1) 和 y 合併
是不是有點妙妙
我喜歡把fy併到fx去耶
合併的時候,d[fy]的變化,畫個圖就比較容易得出來啦
或者像我這樣
d[fy]' + d[y] = d[fx] + d[x - 1] + v
d[fx] = 0
∴d[fy]' = d[fx] - d[y] + v

Code

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#define ll long long
using namespace std;

int w, n, m, fa[107], d[107];  

inline int read(){
    int ans = 0, f = 1;
    char ch = getchar();
    for(; ch < '0' || ch > '9'; ch = getchar())
        if (ch == '-')
            f = 0;
    for(; ch >= '0' && ch <= '9'; ch = getchar())
        ans = (ans << 3) + (ans << 1) + ch - 48;
    return f? ans: -ans;
}
int find(int x){
    if (fa[x] != x){
        int k = fa[x];
        fa[x] = find(fa[x]);
        d[x] += d[k];
    }
    return fa[x];
}
int main(){
    w = read();
    while (w--){
        n = read(),m = read();
        for (int i = 0; i <= n; ++i)
            fa[i] = i, d[i] = 0;
        bool flag = true;
        for (int i = 1; i <= m;  ++i){
            int x = read(), y = read(), v = read();
            int fx = find(x - 1), fy = find(y);
            if (fx != fy){
                fa[fy] = fx;
                d[fy] = d[x - 1] - d[y] + v;
            }
            else
                if (d[y] - d[x - 1] != v)
                    flag = false;
        }   
        if (flag)
            printf("true\n");
        else
            printf("false\n");
    }

    return 0;
}