[BZOJ2654] tree

来源:互联网 发布:软件著作权抵税 编辑:程序博客网 时间:2024/05/15 14:14

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=2654

题目大意

给定一些分为黑白两种的边,询问满足包含t条白边的最小生成树

题解

ORZ cls
如果我们想尽可能的多的白边我们要将白边权值加一个很大的负数
如果我们想尽可能的少的白边我们要将白边权值加一个很大的正数
这个是满足二分的性质的~
所以二分加的权值求最小生成树
注意排序时权值相同白边先行
有一个也可以用相同思想做的题[BZOJ3675] [Apio2014]序列分割

const    maxn=50050;    maxm=100050;var    x:array[0..maxm,1..4]of longint;    fa:array[0..maxn]of longint;    i,j,k:longint;    n,m,t,l,r,mid,ans,sum:longint;procedure sort(l,r:longint);var i,j,a,b,c,d:longint;begin    i:=l; j:=r; a:=x[(l+r)div 2,3]; d:=x[(l+r)div 2,4];    repeat        while (x[i,3]<a)or((a=x[i,3])and(d>x[i,4])) do inc(i);        while (a<x[j,3])or((a=x[j,3])and(d<x[j,4])) do dec(j);        if not(i>j) then        begin            c:=1; b:=x[i,c]; x[i,c]:=x[j,c]; x[j,c]:=b;            c:=2; b:=x[i,c]; x[i,c]:=x[j,c]; x[j,c]:=b;            c:=3; b:=x[i,c]; x[i,c]:=x[j,c]; x[j,c]:=b;            c:=4; b:=x[i,c]; x[i,c]:=x[j,c]; x[j,c]:=b;            inc(i); dec(j);        end;    until i>j;    if l<j then sort(l,j);    if i<r then sort(i,r);end;function get(a:longint):longint;begin    if fa[a]=a then exit(a);    fa[a]:=get(fa[a]);    exit(fa[a]);end;function check(a:longint):longint;var i,tot,b,c:longint;begin    for i:=1 to m do        if x[i,4]=0 then inc(x[i,3],a);    for i:=1 to n do        fa[i]:=i;    sort(1,m);    tot:=0; sum:=0;    for i:=1 to m do        begin            b:=get(x[i,1]); c:=get(x[i,2]);            if b=c then continue;            fa[b]:=c;            inc(sum,x[i,3]);            if x[i,4]=0 then inc(tot);        end;    for i:=1 to m do        if x[i,4]=0 then dec(x[i,3],a);    exit(tot);end;begin    randomize;    readln(n,m,t); ans:=0; sum:=0;    for i:=1 to m do        begin            readln(x[i,1],x[i,2],x[i,3],x[i,4]);            inc(x[i,1]); inc(x[i,2]);        end;    l:=-105; r:=105;    while l<=r do        begin            mid:=(l+r)div 2;            if check(mid)<t            then r:=mid-1            else begin ans:=sum-t*mid; l:=mid+1; end;        end;    writeln(ans);end.
0 0