Cod sursa(job #2224762)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 24 iulie 2018 23:59:57
Problema Arbore partial de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <bits/stdc++.h>

using namespace std;

class UnionFind{
private:
    vector<int> father;

public:

    UnionFind(int n){
        father.resize(n);
    }

    void makeSet(int i){
        father[i] = i;
    }

    int findRoot(int x){
        if (x == father[x])
            return x;
        else
            return father[x] = findRoot(father[x]);
    }

    void combine(int x, int y){
        static std::random_device rd;
        static std::mt19937 mt(rd());
        static uniform_int_distribution<int> distribution(0, 1);

        x = findRoot(x);
        y = findRoot(y);

        if (distribution(mt) & 1){
            int t = x;
            x = y;
            y = t;
        }

        if (x != y){
            father[x] = y;
        }
    }
};

class Edge{
public:

    int x, y, w;

    Edge(){}

    Edge(int a, int b, int c){
        x = a;
        y = b;
        w = c;
    }

    friend istream&operator >> (istream& stream, Edge& edge){
        stream >> edge.x;
        stream >> edge.y;
        stream >> edge.w;
        return stream;
    }

    friend ostream&operator << (ostream& stream, const Edge& edge){
        stream << edge.x << " " << edge.y;
        return stream;
    }

    bool operator < (const Edge& E) const{
        return w < E.w;
    }
};

int main() {
//    ifstream cin("data.txt");
    ifstream cin("apm.in");
    ofstream cout("apm.out");

    ios_base::sync_with_stdio(false);

    int N, M;
    cin >> N >> M;

    vector<Edge> edges(M);

    for (auto &e: edges)
        cin >> e;

    sort(edges.begin(), edges.end());
    UnionFind unionFind(N);

    for (int i = 0; i < N; i++)
        unionFind.makeSet(i);

    vector<Edge> answerEdges;
    int answer = 0;

    for (int i = 0; i < M; i++){
        int x = edges[i].x - 1;
        int y = edges[i].y - 1;

        if (unionFind.findRoot(x) != unionFind.findRoot(y)){
            unionFind.combine(x, y);
            answer += edges[i].w;
            answerEdges.push_back(edges[i]);
        }
    }

    cout << answer << "\n";
    cout << N - 1 << "\n";

    for (auto e: answerEdges)
        cout << e << "\n";

    return 0;
}