嗯A了一道BZOJ上的题> <
好开森呐什么的。。
就是平面图的最小割就是它的对偶图的最短路
听上去很高大上。。其实就是把平面图的那个中间的空空的那个小洞当成一个点,然后两个小洞之间的夹着的那条边的权值就是那两个点之间线的权值
然后注意n=1和m=1的情况
妈蛋被这个坑了好久
Code:
var heap,d,where,headlist:array[0..2000002] of longint;
next,t,weight:array[0..5000002] of longint;
nothing,tot,step,top,step1,step2,num,x,i,j,k,n,m:longint;
function min(A,b:longint):longint;
begin
if a<b then exit(a);
exit(b);
end;
procedure ten;
begin
tot:=maxlongint;
for i:=1 to m-1 do begin
read(d[i]);
tot:=min(tot,d[i]);
end;
writeln(tot);
halt;
end;
procedure tem;
begin
tot:=maxlongint;
for i:=1 to n-1 do begin
read(d[i]);
tot:=min(tot,d[i]);
end;
writeln(tot);
halt;
end;
procedure init;
begin
readln(n,m);
if n=1 then ten;
if m=1 then tem;
for i:=0 to 2*(n-1)*(m-1)+1 do headlist[i]:=-1;
for j:=1 to m-1 do
begin
read(x);
step1:=2*(n-1)*(m-1)+1;
step2:=2*j;
inc(num);
next[num]:=headlist[step2];
headlist[step2]:=num;
t[num]:=step1;
weight[num]:=x;
end;
for i:=2 to n-1 do
for j:=1 to m-1 do
begin
read(x);
step1:=(i-1)*2*(m-1)+j*2;
step2:=step1-(2*(m-1)+1);
inc(num);
next[num]:=headlist[step1];
headlist[step1]:=num;
t[num]:=step2;
weight[num]:=x;
inc(num);
next[num]:=headlist[step2];
headlist[step2]:=num;
t[num]:=step1;
weight[num]:=x;
end;
for j:=1 to m-1 do
begin
read(x);
step1:=0;
step2:=(n-2)*2*(m-1)+1+(j-1)*2;
inc(num);
next[num]:=headlist[step1];
headlist[step1]:=num;
t[num]:=step2;
weight[num]:=x;
end;
for i:=1 to n-1 do
begin
read(x);
step1:=0;
step2:=(i-1)*2*(m-1)+1;
inc(num);
next[num]:=headlist[step1];
headlist[step1]:=num;
t[num]:=step2;
weight[num]:=x;
for j:=2 to m-1 do
begin
read(x);
step1:=(i-1)*2*(m-1)+(j-1)*2;
step2:=step1+1;
inc(num);
next[num]:=headlist[step1];
headlist[step1]:=num;
t[num]:=step2;
weight[num]:=x;
inc(num);
next[num]:=headlist[step2];
headlist[step2]:=num;
t[num]:=step1;
weight[num]:=x;
end;
read(x);
step1:=2*i*(m-1);
step2:=2*(n-1)*(m-1)+1;
inc(num);
next[num]:=headlist[step1];
headlist[step1]:=num;
t[num]:=step2;
weight[num]:=x;
end;
for i:=1 to n-1 do
for j:=1 to m-1 do
begin
read(x);
step1:=(i-1)*2*(m-1)+1+(j-1)*2;
step2:=step1+1;
inc(num);
next[num]:=headlist[step1];
headlist[step1]:=num;
t[num]:=step2;
weight[num]:=x;
inc(num);
next[num]:=headlist[step2];
headlist[step2]:=num;
t[num]:=step1;
weight[num]:=x;
end;
end;
procedure sert(a:longint);
var fa:longint;
begin
if a=1 then exit;
fa:=a shr 1;
if d[heap[fa]]>d[heap[a]] then begin
where[heap[fa]]:=a;
where[heap[a]]:=fa;
step:=heap[a];
heap[a]:=heap[fa];
heap[fa]:=step;
sert(fa);
end;
end;
procedure down(a:longint);
var son1,son2:longint;
begin
son1:=a shl 1;
son2:=a shl 1+1;
if son1>top then exit;
if son1=top then
if d[heap[a]]>d[heap[son1]] then begin
where[heap[a]]:=son1;
where[heap[son1]]:=a;
step:=heap[a];
heap[a]:=heap[son1];
heap[son1]:=step;
exit;
end;
if (d[heap[son1]]<d[heap[son2]]) then
if d[heap[a]]>d[heap[son1]] then begin
where[heap[a]]:=son1;
where[heap[son1]]:=a;
step:=heap[a];
heap[a]:=heap[son1];
heap[son1]:=step;
down(son1);
end
else nothing:=1
else
if d[heap[a]]>d[heap[son2]] then begin
where[heap[a]]:=son2;
where[heap[son2]]:=a;
step:=heap[a];
heap[a]:=heap[son2];
heap[son2]:=step;
down(son2);
end
end;
procedure change(a:longint);
begin
inc(top);
where[a]:=top;
heap[top]:=a;
sert(top);
end;
procedure Dijkstra;
begin
for j:=1 to (n-1)*(m-1)*2+1 do
begin
x:=heap[1];
heap[1]:=heap[top];
where[heap[top]]:=1;
dec(top);
down(1);
i:=headlist[x];
while i<>-1 do
begin
if d[x]+weight[i]<d[t[i]] then if d[t[i]]=maxlongint then begin
d[t[i]]:=d[x]+weight[i];
change(t[i]);
end
else begin
d[t[i]]:=d[x]+weight[i];
sert(where[t[i]]);
end;
i:=next[i];
end;
end;
end;
procedure First;
begin
d[0]:=0;
for i:=1 to 2*(n-1)*(m-1)+1 do d[i]:=maxlongint;
i:=headlist[0];
while (i<>-1) do
begin
if t[i]=(n-2)*2*(m-1)+1 then begin
if tot=1 then if weight[i]<d[t[i]] then begin
d[t[i]]:=weight[i];
sert(where[t[i]]);
end;
inc(tot);
if tot=2 then begin i:=next[i]; continue; end;
end;
d[t[i]]:=weight[i];
change(t[i]);
i:=next[i];
end;
end;
procedure main;
begin
init;
First;
Dijkstra;
writeln(d[(n-1)*2*(m-1)+1]);
end;
begin
main;
end.