BZOJ 2561 最小生成樹 最小割

2021-07-31 03:26:48 字數 2953 閱讀 5791

為什麼刪除最少的邊判連通連最小割都沒想到。。。估計是廢了。。。

考慮kruskal的過程(最小生成樹)如果有一條邊(u,v),若所有比他小的邊能使u,v聯通,這條邊就不必加入生成樹中,最大生成樹也同理。於是我們只要把權值比l小的調出來跑最小割,權值比l大的也挑出來跑最小割。兩個加一下就是答案了。

**:

type

edge=^edgenode;

edgenode=record

t,c,f:longint;

next,rev:edge;

end;

const maxl=1000000000;

var n,m,i,s,t,len,ans:longint;

e:array[0..200100,0..2]of longint;

con:array[0..20010,0..1]of edge;

visit:array[0..20010]of boolean;

ne,dl:array[0..20010]of longint;

procedure

ins(x,y,b:longint);

var p:edge;

begin

new(p);

p^.t:=y;

p^.c:=1;

p^.f:=0;

p^.next:=con[x,b];

con[x,b]:=p;

new(p);

p^.t:=x;

p^.c:=0;

p^.f:=0;

p^.next:=con[y,b];

con[y,b]:=p;

con[x,b]^.rev:=con[y,b];

con[y,b]^.rev:=con[x,b];

end;

function

min(x,y:longint):longint;

begin

if x>y then

exit(y)

else

exit(x);

end;

function

bfs(b:longint):boolean;

var p:edge;

head,tail:longint;

begin

head:=1;

tail:=1;

dl[1]:=s;

ne[s]:=1;

bfs:=false;

while head<=tail do

begin

p:=con[dl[head],b];

if dl[head]=t then bfs:=true;

while p<>nil

dobegin

if (ne[p^.t]=0)and(p^.c>p^.f) then

begin

ne[p^.t]:=ne[dl[head]]+1;

inc(tail);

dl[tail]:=p^.t;

end;

p:=p^.next;

end;

inc(head);

end;

end;

function

dinic

(k,flow,b:longint):longint;

var p:edge;

o:longint;

begin

if k=t then

exit(flow);

if visit[k]=true

then

exit(0);

dinic:=0;

p:=con[k,b];

while p<>nil

dobegin

if (ne[p^.t]=ne[k]+1)and(p^.c>p^.f) then

begin

o:=dinic(p^.t,min(flow,p^.c-p^.f),b);

dinic:=dinic+o;

inc(p^.f,o);

dec(p^.rev^.f,o);

dec(flow,o);

if flow=0

then

break;

end;

p:=p^.next;

end;

if dinic=0

then visit[k]:=true;

end;

begin

readln(n,m);

for i:=1

to m do

readln(e[i,0],e[i,1],e[i,2]);

readln(s,t,len);

for i:=1

to m do

begin

if e[i,2]then

begin ins(e[i,0],e[i,1],0); ins(e[i,1],e[i,0],0); end;

if e[i,2]>len then

begin ins(e[i,0],e[i,1],1); ins(e[i,1],e[i,0],1); end;

end;

ans:=0;

while bfs(0) do

begin

fillchar(visit,sizeof(visit),false);

ans:=ans+dinic(s,maxl,0);

fillchar(ne,sizeof(ne),0);

end;

fillchar(ne,sizeof(ne),0);

while bfs(1) do

begin

fillchar(visit,sizeof(visit),false);

ans:=ans+dinic(s,maxl,1);

fillchar(ne,sizeof(ne),0);

end;

writeln(ans);

end.

bzoj 2561 最小生成樹

給定乙個邊帶正權的連通無向圖g v,e 其中n v m e n個點從1到n依次編號,給定三個正整數u,v,和l u v 假設現在加入一條邊權為l的邊 u,v 那麼需要刪掉最少多少條邊,才能夠使得這條邊既可能出現在最小生成樹上,也可能出現在最大生成樹上?第一行包含用空格隔開的兩個整數,分別為n和m 接...

bzoj2561 最小生成樹

time limit 10 sec memory limit 128 mb submit 1024 solved 520 submit status discuss 給定乙個邊帶正權的連通無向圖g v,e 其中n v m e n個點從1到n依次編號,給定三個正整數u,v,和l u v 假設現在加入一...

bzoj 2561 最小生成樹

給定乙個邊帶正權的連通無向圖,現在加入一條邊權為l的邊 u,v 那麼需要刪掉最少多少條邊,才能夠使得這條邊既可能出現在最小生成樹上,也可能出現在最大生成樹上?以前看著一臉懵逼,現在好像就是那樣。容易想到,當u v存在一條路徑,上面不存在 l的邊,那麼新邊一定不在最小生成樹上,所以將所有小於l的邊建出...