带有限制的生成树
首先不难想到二分答案转化为判定性问题
假设二分出了一个答案p,
首先我们先考虑建一级公路。
由于一级公路费用是大于二级公路的,所以对于那些一级公路花费<=p的道路,
不难想到让他们建一级公路显然更合适。
如果能建一级公路的建道路数>=k
并且再选择二级公路能选到n-1条,说明答案可行
注意这里的道路选择一定要满足生成树的性质,所以我们要加入并查集优化
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 type node=record 2 x,y,c1,c2:longint; 3 end; 4 5 var a:array[0..20010] of node; 6 fa,d:array[0..10010] of longint; 7 mid,i,n,k,l,r,ans,m:longint; 8 9 function getf(x:longint):longint; 10 begin 11 if fa[x]<>x then fa[x]:=getf(fa[x]); 12 exit(fa[x]); 13 end; 14 15 function check(p:longint):boolean; 16 var s,i,k1,k2:longint; 17 begin 18 for i:=1 to n do 19 begin 20 d[i]:=1; 21 fa[i]:=i; 22 end; 23 s:=0; 24 for i:=1 to m do 25 if a[i].c1<=p then 26 begin 27 k1:=getf(a[i].x); 28 k2:=getf(a[i].y); 29 if k1<>k2 then 30 begin 31 if d[k1]>d[k2] then fa[k2]:=k1 32 else begin 33 fa[k1]:=k2; 34 if d[k1]=d[k2] then inc(d[k2]); 35 end; 36 inc(s); 37 end; 38 end; 39 if s<k then exit(false); 40 if s=n-1 then exit(true); 41 for i:=1 to m do 42 if (a[i].c2<=p) and (a[i].c1>p) then 43 begin 44 k1:=getf(a[i].x); 45 k2:=getf(a[i].y); 46 if k1<>k2 then 47 begin 48 if d[k1]>d[k2] then fa[k2]:=k1 49 else begin 50 fa[k1]:=k2; 51 if d[k1]=d[k2] then inc(d[k2]); 52 end; 53 inc(s); 54 if s=n-1 then exit(true); 55 end; 56 end; 57 exit(false); 58 end; 59 60 begin 61 readln(n,k,m); 62 l:=30000; 63 for i:=1 to m-1 do 64 begin 65 with a[i] do 66 begin 67 readln(x,y,c1,c2); 68 end; 69 if a[i].c1>r then r:=a[i].c1; 70 if a[i].c2<l then l:=a[i].c2; 71 end; 72 ans:=r; 73 while l<=r do 74 begin 75 mid:=(l+r) shr 1; 76 if check(mid) then 77 begin 78 ans:=mid; 79 r:=mid-1; 80 end 81 else l:=mid+1; 82 end; 83 writeln(ans); 84 end.