Cod sursa(job #1850005)

Utilizator msciSergiu Marin msci Data 18 ianuarie 2017 01:09:50
Problema Arbore partial de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector<int> par;
  vector<int> rank;
  vector<int> size; 
  int c;

  UnionFind(int n) : par(n), rank(n, 0), size(n, 1), c(n) { for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int find(int i) { 
    return (par[i] == i ? i : (par[i] = find(par[i])));
  }

  bool same(int i, int j) { 
    return find(i) == find(j); 
  }

  int get_size(int i) { 
    return size[find(i)]; 
  }

  int count() { 
    return c; 
  }

  void merge(int i, int j) {
    i = find(i), j = find(j);
    if (i == j) {
      return;
    }
    c--;
    if (rank[i] > rank[j]) {
      swap(i, j);
    }
    par[i] = j; 
    size[j] += size[i];
    if (rank[i] == rank[j]) {
      rank[j]++;
    }
  }
};

struct E {
  int u, v, weight;
  E(int u, int v, int weight) : u(u), v(v), weight(weight) {}
};

bool operator<(const E& a, const E& b) { 
  return a.weight < b.weight;
}

int kruskal(vector<E>& edges, int V) {
  sort(edges.begin(), edges.end());
  int cost = 0, count = 0;
  UnionFind uf(V);
  for (auto& e : edges) {
    if (!uf.same(e.u, e.v)) {
      cost += e.weight;
      uf.merge(e.u, e.v);
      count++;
      if (count == V - 1) {
        break;
      }
    }
  }
  return cost;
}

tuple< int, int, vector< pair<int, int> > > kruskal_extended(vector<E>& edges, int V) {
  sort(edges.begin(), edges.end());
  int cost = 0, count = 0;
  vector< pair<int, int> > ret_edges;
  UnionFind uf(V);
  for (auto& e : edges) {
    if (!uf.same(e.u, e.v)) {
      cost += e.weight;
      uf.merge(e.u, e.v);
      ret_edges.emplace_back(e.u, e.v);
      count++;
      if (count == V - 1) {
        break;
      }
    }
  }
  return make_tuple(cost, count, ret_edges);
}

int main() {
  freopen("apm.in", "r", stdin);
  freopen("apm.out", "w", stdout);
  int n, m;
  scanf("%d %d", &n, &m);
  vector<E> edges;
  for (int i = 0; i < m; i++) {
    int x, y, c;
    scanf("%d %d %d", &x, &y, &c);
    x--, y--;
    edges.emplace_back(x, y, c);
  }
  auto ret = kruskal_extended(edges, n);
  printf("%d\n%d\n", get<0>(ret), get<1>(ret));
  auto vec = get<2>(ret);
  for (auto& e : vec) {
    printf("%d %d\n", e.first + 1, e.second + 1);
  }
  return 0;
}