之前做的时候一直想的都是最小化最大值嘛,于是二分答案,但是怎么都搞不出来。今天看了一眼突然想到其实根本并不用二分哇,把边先按一级费用排序,用kruskal选出最便宜的k条公路,再按二级费用排序,用kruskal求出最小生成树,中间最高的费用就是答案。交上去就AC了…..
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct edge{
int a1,a2,c1,c2;
}G[20005];
bool cmp1(edge a,edge b)
{
return a.c1<b.c1;
}
bool cmp2(edge a,edge b)
{
return a.c2<b.c2;
}
int par[10005];
int find(int x)
{
return x==par[x]?x:par[x]=find(par[x]);
}
bool unite(int x,int y)
{
x=find(x),y=find(y);
if(x==y)return false;
par[x]=y;return true;
}
int main()
{
int n,k,m,i,j,cnt=0,maxn=0;
cin>>n>>k>>m;
for(i=1;i<=n;i++)par[i]=i;
for(i=1;i<m;i++){
scanf("%d%d%d%d",&G[i].a1,&G[i].a2,&G[i].c1,&G[i].c2);
}
sort(G+1,G+m,cmp1);
for(i=1;i<m;i++){
if(unite(G[i].a1,G[i].a2)){
cnt++;maxn=max(maxn,G[i].c1);
}
if(cnt==k)break;
}
sort(G+1+i,G+m,cmp2);
for(i+=1;i<m;i++){
if(unite(G[i].a1,G[i].a2)){
cnt++;maxn=max(G[i].c2,maxn);
}
if(cnt==n-1)break;
}
cout<<maxn<<endl;
return 0;
}