Cod sursa(job #1710278)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 28 mai 2016 18:55:03
Problema Politie Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 3.29 kb
#include <bits/stdc++.h>

using namespace std;

constexpr int MAX_N = 250000;
constexpr int MAX_M = 500000;
constexpr int BUFFSIZE = 258257;

struct Edge {
  int u, v;
  long long cost;
} G[MAX_M];

int pointer[MAX_M];

int root[MAX_N];
int weight[MAX_N];
int costs[MAX_N - 1];

inline char getChar() {
  static char buff[BUFFSIZE];
  static int pos = BUFFSIZE;
  if (pos == BUFFSIZE) {
    assert(fread(buff, 1, BUFFSIZE, stdin));
    pos = 0;
  }
  return buff[pos++];
}

inline int readInt() {
  unsigned q = 0;
  char c;
  do {
    c = getChar();
  } while (!isdigit(c));
  do {
    q = (q << 1) + (q << 3) + (c - '0');
    c = getChar();
  } while (isdigit(c));
  return q;
}

inline int getRoot(int u) {
  int r = u;
  while (root[r] != r)
    r = root[r];
  while (root[u] != u) {
    int v = root[u];
    root[u] = r;
    u = v;
  }
  return r;
}

void unionSet(int u, int v) {
  if (weight[u] >= weight[v]) {
    root[v] = u;
    weight[u] += (weight[v] == weight[u]);
  } else {
    root[u] = v;
  }
}

void insertionSort(int lo, int hi) {
  for (int i = lo + 1; i < hi; i += 1) {
    int x = pointer[i];
    int j = i;
    while ((j > lo) && (G[pointer[j - 1]].cost > G[x].cost)) {
      pointer[j] = pointer[j - 1];
      j -= 1;
    }
    pointer[j] = x;
  }
}

void radixPass(int lo, int hi, int bits) {
  int b[256], e[256];
  memset(e, 0, 4 * 256);
  for (int i = lo; i < hi; i += 1)
    e[(G[pointer[i]].cost >> bits) & 255] += 1;
  b[0] = lo;
  e[0] += lo;
  for (int i = 1; i < 256; i += 1) {
    b[i] = e[i - 1];
    e[i] += e[i - 1];
  }
  for (int i = 0; i < 256; i += 1) {
    while (b[i] != e[i]) {
      int elem = pointer[b[i]];
      int bucket = (G[elem].cost >> bits) & 255;
      while (bucket != i) {
        int tmp = pointer[b[bucket]];
        pointer[b[bucket]++] = elem;
        elem = tmp;
        bucket = (G[elem].cost >> bits) & 255;
      }
      pointer[b[i]++] = elem;
    }
  }
  if (bits) {
    for (int i = 0; i < 256; i += 1) {
      const int m_size = e[i] - (i ? e[i - 1] : lo);
      if (m_size > 100) {
        radixPass(e[i] - m_size, e[i], bits - 8);
      } else if (m_size > 1) {
        insertionSort(e[i] - m_size, e[i]);
      }
    }
  }
}

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

  int n = readInt(), m = readInt(), useless = readInt(), maxDegree = readInt();

  for (int i = 0; i < m; i += 1) {
    G[i].u = readInt() - 1; G[i].v = readInt() - 1; G[i].cost = ((long long) readInt() << 32LL) | readInt();
    pointer[i] = i;
  }
  fclose(stdin);

  radixPass(0, m, 56);

  for (int i = 0; i < n; i += 1) {
    root[i] = i;
    weight[i] = 1;
  }

  int ptr = 0;
  for (int i = 0; i < m; i += 1) {
    const int u = getRoot(G[pointer[i]].u);
    const int v = getRoot(G[pointer[i]].v);
    if (u != v) {
      costs[ptr++] = (G[pointer[i]].cost & ((1LL << 32) - 1));
      unionSet(u, v);
    }
  }

  sort(costs, costs + n - 1, greater <int>());

  int numUnique = 1;
  for (int i = 1; i < n - 1; i += 1)
    if (costs[i] != costs[numUnique - 1])
      costs[numUnique++] = costs[i];

  for (int i = 0; i < maxDegree; i += 1)
    printf("%d\n", costs[i]);

  fclose(stdout);

  return 0;
}