boolUnion(int x, int y){ x = Find(x), y = Find(y); if (x == y) returnfalse; U[x] = y; returntrue; }
intKruskal(){ int whiteEdge = 0; for (int i = 1; i <= V; ++i) U[i] = i; std::sort(edge + 1, edge + 1 + E); int tot = 0; ans = 0; for (int i = 1; i <= E; ++i) { if (Union(edge[i].prev, edge[i].next)) ans += edge[i].weight, ++tot, whiteEdge += (edge[i].color == WHITE); if (tot == V - 1) break; } return whiteEdge; }
boolCheck(int add){ for (int i = 1; i <= E; ++i) { if (edge[i].color == WHITE) edge[i].weight += add; } bool Ans = (Kruskal() >= Need); for (int i = 1; i <= E; ++i) { if (edge[i].color == WHITE) edge[i].weight -= add; } return Ans; }
intmain(){ IMPROVE_IO(); cin >> V >> E >> Need; for (int i = 1; i <= E; ++i) { cin >> edge[i].prev >> edge[i].next >> edge[i].weight >> edge[i].color; ++edge[i].prev; ++edge[i].next; } int l = -MAXW, r = MAXW; int Run = 0; while (l <= r) { int mid = ((l + r) >> 1); if (Check(mid)) { l = mid + 1; Run = mid; } else { r = mid - 1; } } Check(Run); cout << ans - Need * Run << endl; return0; }