为什么删除最少的边判连通连最小割都没想到。。。估计是废了。。。
考虑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 do
begin
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 do
begin
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]<len 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.