Highway construction problem solution problem

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;
} 

Guess you like

Origin www.cnblogs.com/ljk123-de-bo-ke/p/11319028.html