bzoj1196: [HNOI2006]公路修建问题
题目链接
题解
二分,判断能否连通
代码
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
inline int read() {
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9')c = getchar();
while(c <= '9' &&c >= '0')x = x * 10 + c - '0',c = getchar();
return x * f;
}
int n,K,m,Ans;
int fa[10005];
struct Edge{int x,y,c1,c2;}e[20005];
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]);}
int use[20007];
bool check(int x) {
for(int i = 1;i <= n;++ i) fa[i] = i;
memset(use,0,sizeof use);
int cnt = 0;
for(int i = 1;i <= m;++ i) {
if(e[i].c1 > x) continue;
int fx = find(e[i].x),fy = find(e[i].y);
if(fx != fy) fa[fx] = fy,cnt ++, use[i] = 1;
}
if(cnt < K) return 0;
for(int i = 1;i <= m;++ i) {
if(e[i].c2 > x || use[i]) continue;
int fx = find(e[i].x),fy = find(e[i].y);
if(fx != fy) fa[fx] = fy,cnt ++,use[i] = 2;
if(cnt == n - 1)break;
}
if(cnt != n-1) return false;
return true;
}
int ans[20007];
int main() {
n = read(),K = read(),m = read();
for(int i = 1;i < m;++ i)
e[i].x = read(),e[i].y = read(),e[i].c1 = read(),e[i].c2 = read();
int l = 1,r = 30000;
while(l <= r) {
int mid = l + r >> 1;
if(check(mid)) {
for(int i = 1;i < m;++ i)ans[i] = use[i];
Ans = mid,r = mid - 1;
}
else l = mid + 1;
}
printf("%d",Ans);
puts("");
//for(int i = 1;i < m;++ i)
// if(ans[i]) printf("%d %d\n",i,ans[i]);
return 0;
}