Cod sursa(job #2203297)

Utilizator emanuel_rRamneantu Emanuel emanuel_r Data 11 mai 2018 20:16:53
Problema Arbore partial de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.37 kb
#include <bits/stdc++.h>

using namespace std;

class UnionFind{
public:
    vector<int> TT, RG;
    int n;
    UnionFind(int n) : TT(n+1, 0), RG(n+1, 0), n(n) {}
    bool equal(int x, int y){
        return find(x) == find(y);
    }
    int find(int x){
        int p = x, f;
        while(TT[p] != 0)
            p = TT[p];
        while(TT[x] != 0){ // Path compression
            f = TT[x];
            TT[x] = p;
            x = f;
        }
        return x;
    }
    void unite(int x, int y){
        x = find(x);
        y = find(y);

        if(x == y) //Nothing to do
            return;
        if(RG[x] > RG[y]) //Union by rank
            TT[y] = x;
        else if(RG[y] > RG[x])
            TT[x] = y;
        else{
            TT[y] = x;
            RG[x]++;
        }
    }
};

template <typename T>
struct MST{
    vector<vector<pair<int, int> > > G;
    vector<tuple<int, int, T> > E;
    vector<pair<int,int> > F;
    unique_ptr<UnionFind> U;
    int n, m;
    T cost = 0;

    void addEdge(int x, int y, T cost){
        E.emplace_back(x, y, cost);
    }

    void setNM(int n, int m){
        this->n = n;
        this->m = m;
    }

    void build(){
        int num = 0;
        int x, y, c;
        sort(E.begin(), E.end(), [](tuple<int, int, int> t1, tuple<int, int, int> t2) -> bool {return get<2>(t1) < get<2>(t2);});
        G.resize(n+1);
        U = make_unique<UnionFind>(n+1);
        for(auto it = E.begin(); it != E.end() and num < (n - 1); it++){
            tie(x, y, c) = *it;
            if(U->equal(x, y))
                continue;
            U->unite(x, y);
            G[x].emplace_back(y, c);
            G[y].emplace_back(x, c);
            F.emplace_back(x, y);
            cost += c;
        }
    }
};


int n, m;
vector<tuple<int, int, int> > E;
MST<long long> M;

void Read()
{
    freopen("apm.in", "r", stdin);
    freopen("apm.out", "w", stdout);
    cin>>n>>m;
    int x, y, c;
    M.setNM(n, m);
    for(int i = 0; i < m; i++){
        cin>>x>>y>>c;
        M.addEdge(x, y, c);
    }
}

void Solve()
{
    M.build();
}

void Print()
{
    cout<<M.cost<<"\n";
    cout<<n-1<<"\n";
    for(auto& it : M.F)
        cout<<get<0>(it)<<" "<<get<1>(it)<<"\n";
}

int main()
{
    ios::sync_with_stdio(false);

    Read();
    Solve();
    Print();
    return 0;
}