首页 > 代码库 > BJOI2006狼抓兔子

BJOI2006狼抓兔子

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

3 4
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

14

HINT

 

Source

题解:

这因该算是比较经典的平面图转对偶图的例题了

原先我写了一遍,但一直WA,今天下定决心要把它调出来

果然是spj写错了。。。看了检查了几遍的主程序果然没错。。。

clj:你50%的代码时间基本都浪费在调试上

      90%的错误都是傻逼错误。

中枪了。。。

代码:

  1 const maxn=1000000+1000;  2 type node=record  3      from,go,next,w:longint;  4      end;  5 var  i,j,n,m,tot,t,x,s,l,r:longint;  6      head,d,q:array[0..2*maxn] of longint;  7      v:array[0..2*maxn] of boolean;  8      e:array[0..6*maxn] of node;  9      num:array[0..1010,0..1010,1..2] of longint; 10 procedure ins(x,y,z:longint); 11  begin 12    inc(tot); 13    e[tot].from:=x;e[tot].go:=y;e[tot].w:=z;e[tot].next:=head[x];head[x]:=tot; 14  end; 15 procedure insert(x,y,z:longint); 16  begin 17    ins(x,y,z);ins(y,x,z); 18  end; 19  20 procedure spfa; 21  var i,x,y:longint; 22    begin 23      fillchar(d,sizeof(d),60); 24      fillchar(v,sizeof(v),false); 25      l:=0;r:=1;q[1]:=s;d[s]:=0;v[s]:=true; 26      while l<r do 27       begin 28        l:=l mod (2*maxn)+1; 29        x:=q[l];v[x]:=false; 30        i:=head[x]; 31        while i<>0 do 32          begin 33           y:=e[i].go; 34           if d[x]+e[i].w<d[y] then 35             begin 36               d[y]:=d[x]+e[i].w; 37               if not(v[y]) then 38                 begin 39                   v[y]:=true; 40                   r:=r mod (2*maxn)+1; 41                   q[r]:=y; 42                 end; 43             end; 44           i:=e[i].next; 45          end; 46       end; 47    end; 48 procedure  spj; 49  var ans,i,x:longint; 50  begin 51    ans:=999999999; 52    for i:=1 to n+m-2 do 53     begin 54      read(x); 55      if x<ans then ans:=x; 56     end; 57    writeln(ans); 58  end; 59  60 procedure init; 61  begin 62    readln(n,m);s:=0;t:=2*n*m+1; 63    if (n=1) or (m=1) then exit; 64    for i:=1 to n do for j:=1 to m do num[i,j,1]:=(i-1)*m+j; 65    for i:=1 to n do for j:=1 to m do num[i,j,2]:=num[i,j,1]+n*m; 66    for i:=1 to n do 67     for j:=1 to m-1 do 68      begin 69       read(x); 70       if i=1 then insert(num[i,j,2],t,x) 71       else if i=n then insert(s,num[i-1,j,1],x) 72       else insert(num[i,j,2],num[i-1,j,1],x); 73      end; 74    for i:=1 to n-1 do 75     for j:=1 to m do 76      begin 77       read(x); 78       if j=1 then insert(s,num[i,j,1],x) 79       else if j=m then insert(num[i,j-1,2],t,x) 80       else insert(num[i,j-1,2],num[i,j,1],x); 81      end; 82    for i:=1 to n-1 do 83     for j:=1 to m-1 do 84      begin 85       read(x); 86       insert(num[i,j,1],num[i,j,2],x) 87      end; 88  end; 89 procedure main; 90  begin 91    spfa; 92    writeln(d[t]); 93  end; 94 begin 95   assign(input,input.txt);assign(output,output.txt); 96   reset(input);rewrite(output); 97   init; 98   if (n=1) or (m=1) then spj else  main; 99   close(input);close(output);100 end.   
View Code