Pagini recente » Cod sursa (job #1133625) | Cod sursa (job #2327943) | Cod sursa (job #576559) | Cod sursa (job #558468) | Cod sursa (job #1710278)
#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;
}