Cod sursa(job #1708547)

Utilizator neapuiuComisie ICPC UPB neapuiu Data 27 mai 2016 12:29:29
Problema Politie Scor Ascuns
Compilator cpp Status done
Runda Marime 1.72 kb
// Andrei Parvu - O(M(logM + log*N)) - Kruskal

#include <cstdio>
#include <vector>
#include <algorithm>
#include <cassert>

using namespace std;

#define ii pair<int, int>
#define x first
#define y second

const int N = 250000;
const int M = 500000;

int h[N + 1], father[N + 1];

void el_union(int x, int y) {
  if (h[x] < h[y]) {
    father[x] = y;
  } else {
    if (h[x] == h[y]) {
      h[x]++;
    }
    father[y] = x;
  }
}

int el_find(int x) {
  int y = x;

  for (; father[x]; x = father[x]);

  for (; father[y]; ) {
    int z = father[y];
    father[y] = x;
    y = z;
  }

  return x;
}

int main() {
  freopen("politie.in", "rt", stdin);
  freopen("politie.out", "wt", stdout);

  int n, m, k, q;
  assert(scanf("%d%d%d%d", &n, &m, &k, &q) == 4);
  assert(1 <= n && n <= N);
  assert(1 <= m && m <= M);
  assert(1 <= k && k <= N);
  assert(1 <= q && q < n);

  vector<pair<ii, ii> > v(m);

  for (int i = 0; i < m; i++) {
    int x, y, t, c;

    assert(scanf("%d%d%d%d", &x, &y, &t, &c) == 4);
    assert(1 <= x && x <= n);
    assert(1 <= y && y <= n);
    assert(x != y);
    assert(1 <= t && t <= k);
    assert(1 <= c && c <= 1000000000);

    v[i] = make_pair(make_pair(t, c), make_pair(x, y));
  }

  sort(v.begin(), v.end());

  vector<int> costs;
  for (int i = 0; i < m; i++) {
    int x = el_find(v[i].y.x), y = el_find(v[i].y.y);

    if (x != y) {
      costs.push_back(v[i].x.y);
      el_union(x, y);
    }
  }

  //fprintf(stderr, "%d\n", costs.size());

  sort(costs.begin(), costs.end());
  int first = -1;
  int cnt = 0;
  for (int i = n - 2; i >= 0 && cnt < q; i--) {
    if (first == -1 || costs[i] != first) {
      printf("%d\n", costs[i]);
      first = costs[i];
      cnt++;
    }
  }

  assert(cnt == q);

  return 0;
}