题意:在所有的边中找到一些边,删去后使start(1,1) 到 end(n,m) 的路径为空集,且权值和最小
其实已经很显然是最小割的模板了=w=
一看数据范围,最小割显然过不去
然而我的dinic过去了...(顺便帮我赌赢了一顿饭..0.0)
只能说,应该是数据(图) 比较水....
var
n,m,l,x,ans :longint;
i,j :longint;
num :array[0..1010,0..1010] of longint;
last,que,dis :array[0..1000010] of longint;
pre,other,len :array[0..6000010] of longint;
function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end;
procedure connect(x,y,z:longint);
begin
inc(l);
pre[l]:=last[x];
last[x]:=l;
other[l]:=y;
len[l]:=z;
end;
function bfs:boolean;
var
p,q,cur,h,tl,i:longint;
begin
for i:=1 to n*m do dis[i]:=0;
h:=0;tl:=1;
que[1]:=1;dis[1]:=1;
while (h<>tl) do
begin
h:=h mod 1000005+1;
cur:=que[h];
q:=last[cur];
while (q<>0) do
begin
p:=other[q];
if (dis[p]=0) and (len[q]>0) then
begin
dis[p]:=dis[cur]+1;
tl:=tl mod 1000005+1;
que[tl]:=p;
if (p=n*m) then exit(true);
end;
q:=pre[q];
end;
end;
exit(false);
end;
function dinic(x,flow:Longint):longint;
var
p,q,rest,tt:longint;
begin
if x=n*m then exit(flow);
rest:=flow;
q:=last[x];
while (q<>0) do
begin
p:=other[q];
if (dis[p]=dis[x]+1) and (len[q]>0) and (rest>0) then
begin
tt:=dinic(p,min(rest,len[q]));
dec(len[q],tt);
dec(rest,tt);
inc(len[q xor 1],tt);
if (rest=0) then exit(flow);
end;
q:=pre[q];
end;
if rest=flow then dis[x]:=0;
exit(flow-rest);
end;
begin
read(n,m);l:=1;
for i:=1 to n do
for j:=1 to m do num[i,j]:=(i-1)*m+j;
//
for i:=1 to n do
for j:=1 to m-1 do
begin
read(x);
connect(num[i,j],num[i,j+1],x);
connect(num[i,j+1],num[i,j],x);
end;
//
for i:=1 to n-1 do
for j:=1 to m do
begin
read(x);
connect(num[i,j],num[i+1,j],x);
connect(num[i+1,j],num[i,j],x);
end;
for i:=1 to n-1 do
for j:=1 to m-1 do
begin
read(x);
connect(num[i,j],num[i+1,j+1],x);
connect(num[i+1,j+1],num[i,j],x);
end;
//
ans:=0;
while bfs do inc(ans,dinic(1,maxlongint div 10));
writeln(ans);
end.
——by Eirlys