Pagini recente » Cod sursa (job #918317) | Cod sursa (job #1411818) | Cod sursa (job #1155875) | Cod sursa (job #864882) | Cod sursa (job #1709655)
#include <bits/stdc++.h>
using namespace std;
const int N_MAX = 250005;
const int D_MAX = 250005;
const int FACTOR = 1000000;
class Edge {
public:
int from;
int to;
int risk;
Edge(int _from = 0, int _to = 0, int _risk = 0) :
from(_from), to(_to), risk(_risk) {}
};
int N, M, D, P;
mt19937 rGen(chrono :: high_resolution_clock :: now().time_since_epoch().count());
vector<Edge> edges[D_MAX];
int father[N_MAX];
unordered_map<int64_t, int> minRisk;
set<int, greater<int>> usedRisks;
vector<pair<int, pair<int, int>>> temp;
inline int64_t PairToLong(int x, int y) {
return 1LL * x * FACTOR + y;
}
inline pair<int, int> LongToPair(int64_t x) {
return make_pair(x / FACTOR, x % FACTOR);
}
int Find(int x) {
if(x != father[x])
father[x] = Find(father[x]);
return father[x];
}
void Merge(int x, int y) {
int fx = Find(x);
int fy = Find(y);
if(fx != fy) {
if(rGen() & 1) swap(fx, fy);
father[fx] = fy;
}
}
int main() {
ifstream f("politie.in");
ofstream g("politie.out");
f >> N >> M >> D >> P;
for(int i = 1, x, y, d, r; i <= M; i++) {
f >> x >> y >> d >> r;
edges[d].push_back(Edge(x, y, r));
}
for(int i = 1; i <= N; i++)
father[i] = i;
for(int i = 1; i <= D; i++) {
minRisk.clear();
for(vector<Edge> :: iterator it = edges[i].begin(); it != edges[i].end(); ++it) {
int x = min(Find(it->from), Find(it->to));
int y = max(Find(it->from), Find(it->to));
if(x != y) {
int64_t key = PairToLong(x, y);
unordered_map<int64_t, int> :: iterator mapIt = minRisk.find(key);
if(mapIt == minRisk.end()) {
minRisk.insert(make_pair(key, it->risk));
} else {
mapIt->second = min(mapIt->second, it->risk);
}
}
}
temp.clear();
for(unordered_map<int64_t, int> :: iterator it = minRisk.begin(); it != minRisk.end(); ++it) {
pair<int, int> key = LongToPair(it->first);
int x = key.first;
int y = key.second;
temp.push_back(make_pair(it->second, make_pair(x, y)));
}
sort(temp.begin(), temp.end());
for(vector<pair<int, pair<int, int>>> :: iterator it = temp.begin(); it != temp.end(); it++) {
if(Find(it->second.first) != Find(it->second.second)) {
Merge(it->second.first, it->second.second);
usedRisks.insert(it->first);
}
}
}
set<int, greater<int>> :: iterator it = usedRisks.begin();
for(int i = 1; i <= P; i++, it++)
g << *it << '\n';
return 0;
}