int n, m, need; structEdge { int u, v, w, cl; }e[M];
int fa[N]; intfind(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]); }
inlinevoidInput(){ read(n, m, need); for(int i = 1; i <= m; i++) { read(e[i].u, e[i].v, e[i].w, e[i].cl); e[i].u++, e[i].v++; } }
inlineboolCheck(int mid, int &ans){ for(int i = 1; i <= m; i++) if(e[i].cl == 0) e[i].w += mid; // add a num to white edge // if the number of white edge in mst is bigger than need , // we need make mid more big for(int i = 1; i <= n; i++) fa[i] = i; sort(e + 1, e + m + 1, [](Edge a, Edge b) { if(a.w == b.w) return a.cl < b.cl; return a.w < b.w; }); int sum = 0, cnt = 0; for(int i = 1; i <= m; i++) { int u = find(e[i].u); int v = find(e[i].v); if(u == v) continue; fa[u] = v; sum += e[i].w; if(e[i].cl == 0) cnt++; } for(int i = 1; i <= m; i++) if(e[i].cl == 0) e[i].w -= mid; if(cnt >= need) { ans = sum - need * mid; return1; } return0; }
inlinevoidWork(){ int l = -200, r = 200, best = -1; while(l <= r) { int mid = l + r >> 1; if(Check(mid, best)) { l = mid + 1; } else { r = mid - 1; } } printf("%d\n", best); }
intmain(){ int T = 1; while(T--) { Input(); Work(); } return0; }