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

 

你可能感兴趣的:(2007)