Cod sursa(job #882576)

Utilizator sebii_cSebastian Claici sebii_c Data 19 februarie 2013 11:11:39
Problema Arbore partial de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <cstdio>

#include <algorithm>
#include <vector>

using namespace std;

const int MAXN = 200001;

int parent[MAXN];
int rank[MAXN];

int find(int x)
{
    int y = x;
    while (x != parent[x])
        x = parent[x];

    while (y != parent[y]) {
        int aux = parent[y];
        parent[y] = x;
        y = aux;
    }

    return x;
}

void unite(int x, int y)
{
    if (rank[x] > rank[y])
        parent[y] = x;
    else
        parent[x] = y;

    if (rank[x] == rank[y])
        rank[y]++;
}

struct edge {
    int from, to;
    int cost;

    edge(int _from, int _to, int _cost): 
        from(_from), to(_to), cost(_cost) {}
};

bool comp(const edge& a, const edge& b)
{
    return a.cost < b.cost;
}

void kruskal(vector<edge>& edges, int n)
{
    for (int i = 1; i <= n; ++i)
        parent[i] = i;

    int total_cost = 0;
    vector<edge> sol;
    for (int id = 0; id < edges.size(); ++id) {
        int from = edges[id].from;
        int to = edges[id].to;
        if (find(from) != find(to)) {
            unite(find(from), find(to));
            total_cost += edges[id].cost;
            sol.push_back(edges[id]);
        }
    }

    printf("%d\n", total_cost);
    printf("%lu\n", sol.size());
    vector<edge>::iterator it;
    for (it = sol.begin(); it != sol.end(); ++it) 
        printf("%d %d\n", it->from, it->to);
}

int main()
{
    freopen("apm.in", "r", stdin);
    freopen("apm.out", "w", stdout);

    int n, m;
    scanf("%d %d", &n, &m);
    vector<edge> edges;
    for (int i = 0; i < m; ++i) {
        int x, y, c;
        scanf("%d %d %d", &x, &y, &c);
        edges.push_back(edge(x, y, c));
    }

    sort(edges.begin(), edges.end(), comp);
    kruskal(edges, n);

    return 0;
}