Highway construction problem solution problem
I saw the title of "most expensive highway minimal"
We think of half,
Ever since, we have the biggest edge x,
Also the conditions to be met are:
1. There are k takes a road less than x, and this article does not constitute a ring k (because there are k tree to a road)
All it takes less than 2 x roads can constitute a minimum spanning tree
Maintain communication with disjoint-set, plus you can add as much as possible with the idea of Kruskal.
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=20006;
int n,k,m,p,t,f[N];
struct xd{int x,y,c1,c2;}a[N];
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
int getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
bool merge(int u,int v){
u=getf(u),v=getf(v);
if(u==v) return 0;
f[u]=v; return 1;
}
bool check(int u){
p=0;
for(int i=1;i<=n;++i) f[i]=i;
for(int i=1;i<=m;++i) if(a[i].c1<=u) if(merge(a[i].x,a[i].y)) ++p;
if(p<k) return 0;
for(int i=1;i<=m;++i) if(a[i].c2<=u) if(merge(a[i].x,a[i].y)) ++p;
if(p<n-1) return 0;
return 1;
}
int ef(int l,int r){
int mid=(l+r>>1);
if(l==r) return l;
if(check(mid)) return ef(l,mid);
else return ef(mid+1,r);
}
int main(){
n=read(),k=read(),m=read()-1;
for(int i=1;i<=m;++i) a[i].x=read(),a[i].y=read(),a[i].c1=read(),a[i].c2=read();
t=ef(1,30000),printf("%d\n",t);
for(int i=1;i<=n;++i) f[i]=i;
for(int i=1;i<=m;++i) if(a[i].c1<=t) if(merge(a[i].x,a[i].y)) printf("%d %d\n",i,1);
for(int i=1;i<=m;++i) if(a[i].c2<=t) if(merge(a[i].x,a[i].y)) printf("%d %d\n",i,2);
return 0;
}