您的位置:首页 > 其它

[BZOJ2654] tree

2016-02-22 11:39 344 查看

传送门

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: