Files
SH-Quizzes/ACMOJ-1812.cpp
2024-04-18 18:38:55 +08:00

100 lines
2.5 KiB
C++

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
template <typename T>
void MergeSort(T *beg, T *end, bool (*cmp)(const T &, const T &)) {
if (end - beg <= 1) return;
size_t len = end - beg;
T *mid = beg + (len >> 1);
MergeSort(beg, mid, cmp);
MergeSort(mid, end, cmp);
T *tmp = new T[len];
T *cur_tmp = tmp, *cur_L = beg, *cur_R = mid;
while ((cur_L < mid) && (cur_R < end)) {
if (cmp(*cur_L, *cur_R))
*(cur_tmp++) = *(cur_L++);
else
*(cur_tmp++) = *(cur_R++);
}
while (cur_L < mid) *(cur_tmp++) = *(cur_L++);
while (cur_R < end) *(cur_tmp++) = *(cur_R++);
cur_tmp = tmp;
T *cur_dst = beg;
while (cur_dst < end) *(cur_dst++) = *(cur_tmp++);
delete[] tmp;
}
typedef long long LL;
typedef long double LDB;
const int kMaxN = 5e4 + 10;
const int kMaxM = 1e5 + 10;
int n, m, K;
struct Edge {
int u, v, w;
bool is_white;
} edge[kMaxM];
int penalty_for_white;
bool Cmp(const Edge &A, const Edge &B) {
int wa = (A.is_white ? A.w + penalty_for_white : A.w);
int wb = (B.is_white ? B.w + penalty_for_white : B.w);
if (wa == wb) return (int)A.is_white > (int)B.is_white;
return wa < wb;
}
int fa[kMaxN];
inline int ff(int u) {
int x = u, y;
while (fa[u] != u) u = fa[u];
while (x != u) {
y = fa[x];
fa[x] = u;
x = y;
}
return u;
}
void Calc(LL &res, int &white_used_count) {
white_used_count = 0;
res = 0;
MergeSort(edge, edge + m, Cmp);
for (int i = 0; i <= n; i++) fa[i] = i;
for (int i = 0; i < m; i++) {
int u = edge[i].u;
int v = edge[i].v;
int w = edge[i].is_white ? edge[i].w + penalty_for_white : edge[i].w;
if (ff(u) == ff(v)) continue;
fa[ff(u)] = ff(v);
if (edge[i].is_white) white_used_count++;
res += w;
}
}
int main() {
#ifdef local
freopen("pro.in", "r", stdin);
#endif
scanf("%d%d%d", &n, &m, &K);
for (int i = 0; i < m; i++) {
int u, v, w, col;
scanf("%d%d%d%d", &u, &v, &w, &col);
edge[i] = Edge{u, v, w, bool(col == 0)};
}
int L = -110, R = 110;
LL ans = 0x3f3f3f3f3f3f3f3f;
while (L < R) {
int M = (L + R) >> 1;
penalty_for_white = M;
LL res;
int white_used_count;
Calc(res, white_used_count);
// printf("mid=%d flag=%d\n",M,int(white_used_count >= K));
if (white_used_count >= K) {
ans = res - K * (LL)penalty_for_white;
// printf("ans=%lld mid=%d\n",ans,M);
L = M + 1;
} else if (white_used_count < K) {
R = M;
}
}
if (0x3f3f3f3f3f3f3f3f == ans) ans = -1;
printf("%lld\n", ans);
return 0;
}