1066: [SCOI2007]蜥蜴 - BZOJ

Description

在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。
Input

输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。
Output

输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。
Sample Input
5 8 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........

Sample Output
1

HINT

100%的数据满足:1<=r, c<=20, 1<=d<=3

 

网络流水题

把蜥蜴都当成流,每一个岩石都拆点,中间流量为高度

从s向有蜥蜴的岩石的入点连容量为1的边,从可以逃离的岩石的出点向t连容量为inf的边

i点可以到达j点,就从i的出点向j的入点连容量为inf的边

跑一遍最大流,用蜥蜴的数量减去最大流就是答案

傻叉错误:把二维坐标转换成一维坐标时搞错了,结果50分

  1 const
  2         maxn=810;
  3         inf=800000;
  4 var
  5         map:array[0..maxn,0..maxn]of longint;
  6         r,c,d,num,s,t:longint;
  7 
  8 function calc(x,y:longint):longint;
  9 begin
 10         exit((x-1)*c+y);
 11 end;
 12 
 13 procedure init;
 14 var
 15         i,j,k,l:longint;
 16         ch:char;
 17 begin
 18         readln(r,c,d);
 19         s:=0;
 20         t:=r*c*2+1;
 21         for i:=1 to r do
 22           begin
 23             for j:=1 to c do
 24               begin
 25                 read(ch);
 26                 map[calc(i,j),calc(i,j)+r*c]:=ord(ch)-ord('0');
 27               end;
 28             readln;
 29           end;
 30         for i:=1 to r do
 31           begin
 32             for j:=1 to c do
 33               begin
 34                 read(ch);
 35                 if ch='L' then
 36                 begin
 37                   map[s,calc(i,j)]:=1;
 38                   inc(num);
 39                 end;
 40               end;
 41             readln;
 42           end;
 43         for i:=1 to r do
 44           for j:=1 to c do
 45             if (i<=d) or (j<=d) or (r-i+1<=d) or (c-j+1<=d) then map[calc(i,j)+r*c,t]:=inf;
 46         for i:=1 to r do
 47           for j:=1 to c do
 48             for k:=-d to d do
 49               for l:=-d to d do
 50                 if (i+k>0) and (i+k<=r) and (j+l>0) and (j+l<=c) and (d*d>=k*k+l*l) then map[calc(i,j)+r*c,calc(i+k,j+l)]:=inf;
 51 
 52 end;
 53 
 54 var
 55         dis,vh,his,pre:array[0..maxn]of longint;
 56         aug,flow:longint;
 57         flag:boolean;
 58 
 59 procedure sap;
 60 var
 61         i,j,min:longint;
 62 begin
 63         vh[0]:=t+1;
 64         i:=s;
 65         aug:=inf;
 66         while dis[i]<=t do
 67           begin
 68             his[i]:=aug;
 69             flag:=false;
 70             for j:=s to t do
 71               if (map[i,j]>0) and (dis[i]=dis[j]+1) then
 72               begin
 73                 flag:=true;
 74                 if aug>map[i,j] then aug:=map[i,j];
 75                 pre[j]:=i;
 76                 i:=j;
 77                 if i=t then
 78                 begin
 79                   inc(flow,aug);
 80                   while i<>s do
 81                     begin
 82                       inc(map[i,pre[i]],aug);
 83                       dec(map[pre[i],i],aug);
 84                       i:=pre[i];
 85                     end;
 86                   aug:=inf;
 87                 end;
 88                 break;
 89               end;
 90             if flag then continue;
 91             min:=t;
 92             for j:=s to t do
 93               if (map[i,j]>0) and (min>dis[j]) then min:=dis[j];
 94             dec(vh[dis[i]]);
 95             if vh[dis[i]]=0 then break;
 96             dis[i]:=min+1;
 97             inc(vh[min+1]);
 98             if i<>s then
 99             begin
100               i:=pre[i];
101               aug:=his[i];
102             end;
103           end;
104         writeln(num-flow);
105 end;
106 
107 begin
108         init;
109         sap;
110 end.
View Code

 

posted @ 2014-04-22 20:42  Randolph87  阅读(273)  评论(0编辑  收藏  举报