首先看完题,我们会发现,这道题要求一个最小生成树,基本就是一个克鲁斯卡尔的板题,但是,仔细一看,会发现,有俩个边权,第一个边权必须要达到K,而第二个比第一个小,没有限制
很明显,要先给第一个排序,然后,就连K条边,这样,就解决了K个一级路
然后,可以把第二个排序,排完后,连剩下的边,然后,在执行时,求连的边最大值,然后,不就是道板题吗
注意,边要开两倍
#include<bits/stdc++.h> using namespace std; int n,m,k; int ans=0; int x,y,c1,c2,u1,v1; int fa[10005]; int jl; struct edge{ int u,v,val1,val2; }e[20005]; int find(int x) { if(fa[x]==x) { return x; } else { fa[x]=find(fa[x]); return fa[x]; } } bool cmp(edge x,edge y) { if(x.val1==y.val1) { return x.val2>y.val2; } else { return x.val1<y.val1; } } bool kmp(edge x,edge y) { return x.val2<y.val2; } int main() { scanf("%d %d%d",&n,&k,&m); for(int i=1;i<=n;i++) { fa[i]=i; } for(int i=1;i<m;i++) { scanf("%d %d%d %d",&x,&y,&c1,&c2); e[i].u=x; e[i].v=y; e[i].val1=c1; e[i].val2=c2; } int tot=0; sort(e+1,e+m,cmp); for(int i=1;i<m;i++) { int u=e[i].u; int v=e[i].v; int val=e[i].val1; if(find(u)!=find(v)) { fa[find(u)]=find(v); if(ans<val) { ans=val; } tot++; } if(tot==k) { break; } } sort(e+1,e+m,kmp); for(int i=1;i<m;i++) { int u=e[i].u; int v=e[i].v; int val=e[i].val2; if(find(u)!=find(v)) { fa[find(u)]=find(v); if(ans<val) { ans=val; } tot++; } if(tot==n) { break; } } printf("%d",ans); return 0; }跪求二分解法(详解)