1001: [BeiJing2006]狼抓兔子
Time Limit: 15 Sec Memory Limit: 162 MB
Submit: 9967 Solved: 2267
[Submit][Status]
Description
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全*这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.
Input
第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M
Output
输出一个整数,表示参与伏击的狼的最小数量.
Sample Input
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
Sample Output
HINT
Source
题解:
这因该算是比较经典的平面图转对偶图的例题了
原先我写了一遍,但一直WA,今天下定决心要把它调出来
果然是spj写错了。。。看了检查了几遍的主程序果然没错。。。
clj:你50%的代码时间基本都浪费在调试上
90%的错误都是傻逼错误。
中枪了。。。
代码:
const maxn=+;
type node=record
from,go,next,w:longint;
end;
var i,j,n,m,tot,t,x,s,l,r:longint;
head,d,q:array[..*maxn] of longint;
v:array[..*maxn] of boolean;
e:array[..*maxn] of node;
num:array[..,..,..] of longint;
procedure ins(x,y,z:longint);
begin
inc(tot);
e[tot].from:=x;e[tot].go:=y;e[tot].w:=z;e[tot].next:=head[x];head[x]:=tot;
end;
procedure insert(x,y,z:longint);
begin
ins(x,y,z);ins(y,x,z);
end; procedure spfa;
var i,x,y:longint;
begin
fillchar(d,sizeof(d),);
fillchar(v,sizeof(v),false);
l:=;r:=;q[]:=s;d[s]:=;v[s]:=true;
while l<r do
begin
l:=l mod (*maxn)+;
x:=q[l];v[x]:=false;
i:=head[x];
while i<> do
begin
y:=e[i].go;
if d[x]+e[i].w<d[y] then
begin
d[y]:=d[x]+e[i].w;
if not(v[y]) then
begin
v[y]:=true;
r:=r mod (*maxn)+;
q[r]:=y;
end;
end;
i:=e[i].next;
end;
end;
end;
procedure spj;
var ans,i,x:longint;
begin
ans:=;
for i:= to n+m- do
begin
read(x);
if x<ans then ans:=x;
end;
writeln(ans);
end; procedure init;
begin
readln(n,m);s:=;t:=*n*m+;
if (n=) or (m=) then exit;
for i:= to n do for j:= to m do num[i,j,]:=(i-)*m+j;
for i:= to n do for j:= to m do num[i,j,]:=num[i,j,]+n*m;
for i:= to n do
for j:= to m- do
begin
read(x);
if i= then insert(num[i,j,],t,x)
else if i=n then insert(s,num[i-,j,],x)
else insert(num[i,j,],num[i-,j,],x);
end;
for i:= to n- do
for j:= to m do
begin
read(x);
if j= then insert(s,num[i,j,],x)
else if j=m then insert(num[i,j-,],t,x)
else insert(num[i,j-,],num[i,j,],x);
end;
for i:= to n- do
for j:= to m- do
begin
read(x);
insert(num[i,j,],num[i,j,],x)
end;
end;
procedure main;
begin
spfa;
writeln(d[t]);
end;
begin
assign(input,'input.txt');assign(output,'output.txt');
reset(input);rewrite(output);
init;
if (n=) or (m=) then spj else main;
close(input);close(output);
end.