kyopro_library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub dyktr06/kyopro_library

:heavy_check_mark: test/aoj/dsl/dsl_1_b_1.test.cpp

Depends on

Code

#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_B"
#include <bits/stdc++.h>
using namespace std;

#include "../../../lib/data_structure/dynamic_weighted_union_find.hpp"

int main(){
    int n, q; cin >> n >> q;
    DynamicWeightedUnionFind<int> tree;
    while(q--){
        int t; cin >> t;
        if(t == 0){
            int x, y, z; cin >> x >> y >> z;
            tree.unite(x, y, z);
        }else{
            int x, y; cin >> x >> y;
            if(tree.same(x, y)){
                cout << tree.diff(x, y) << "\n";
            }else{
                cout << "?" << "\n";
            }
        }
    }
}
#line 1 "test/aoj/dsl/dsl_1_b_1.test.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_B"
#include <bits/stdc++.h>
using namespace std;

#line 2 "lib/data_structure/dynamic_weighted_union_find.hpp"

template <typename T>
struct DynamicWeightedUnionFind{
    map<long long, long long> par, rank, siz;
    map<T, T> diff_weight;
    T e;

    DynamicWeightedUnionFind(const T &_e = 0) : e(_e){
    }

    void init(const T &x){
        par[x] = x;
        rank[x] = 0;
        siz[x] = 1;
        diff_weight[x] = e;
    }

    int root(const int x){
        if(par.find(x) == par.end()){
            init(x);
        }
        if(par[x] == x){
            return x;
        }
        int rx = root(par[x]);
        diff_weight[x] += diff_weight[par[x]];
        return par[x] = rx;
    }

    T weight(const int x){
        root(x);
        return diff_weight[x];
    }

    T diff(const int x, const int y){
        return weight(y) - weight(x);
    }

    void unite(const int x, const int y, T w){
        if(par.find(x) == par.end()){
            init(x);
        }
        if(par.find(y) == par.end()){
            init(y);
        }
        w += weight(x);
        w -= weight(y);

        int rx = root(x);
        int ry = root(y);
        if(rx == ry) return;

        if(rank[rx] < rank[ry]){
            swap(rx, ry);
            w = -w;
        }

        par[ry] = rx;
        siz[rx] += siz[ry];
        diff_weight[ry] = w;
        if(rank[rx] == rank[ry]) ++rank[rx];
    }

    bool same(const int x, const int y){
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }

    int size(const int x){
        return siz[root(x)];
    }
};
#line 6 "test/aoj/dsl/dsl_1_b_1.test.cpp"

int main(){
    int n, q; cin >> n >> q;
    DynamicWeightedUnionFind<int> tree;
    while(q--){
        int t; cin >> t;
        if(t == 0){
            int x, y, z; cin >> x >> y >> z;
            tree.unite(x, y, z);
        }else{
            int x, y; cin >> x >> y;
            if(tree.same(x, y)){
                cout << tree.diff(x, y) << "\n";
            }else{
                cout << "?" << "\n";
            }
        }
    }
}
Back to top page