SCOI2007蜥蜴

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

题解:

网络流真是神奇!关键在构图!

点容量---拆点

无源无汇---附加源和汇

代码:(调了很长时间,结果竟然是insert写错了……)

  1 uses math;
  2 const inf=maxlongint;
  3 type node=record
  4      go,next,v:longint;
  5      end;
  6 var e:array[0..50000] of node;
  7     cnt,i,r,c,d,j,k,l,ans,tot,s,t:longint;
  8     num:array[0..25,0..25,1..2] of longint;
  9     first,h,q,cur:array[0..1000] of longint;
 10     a:array[0..25,0..25] of char;
 11     ch:char;
 12 procedure ins(u,v,w:longint);
 13  begin
 14  inc(cnt);
 15  e[cnt].go:=v;e[cnt].v:=w;e[cnt].next:=first[u];first[u]:=cnt;
 16  end;
 17 procedure insert(u,v,w:longint);
 18  begin
 19  ins(u,v,w);ins(v,u,0);
 20  end;
 21 function bfs:boolean;
 22  var i,x,y,head,tail:longint;
 23  begin
 24  fillchar(h,sizeof(h),0);
 25  head:=0;tail:=1;q[1]:=s;h[s]:=1;
 26  while head<tail do
 27   begin
 28   inc(head);
 29   x:=q[head];
 30   i:=first[x];
 31   while i<>0 do
 32    begin
 33     y:=e[i].go;
 34     if (h[y]=0) and (e[i].v<>0) then
 35      begin
 36       h[y]:=h[x]+1;
 37       inc(tail);
 38       q[tail]:=y;
 39      end;
 40     i:=e[i].next;
 41    end;
 42   end;
 43  exit(h[t]<>0);
 44  end;
 45 function dfs(x,f:longint):longint;
 46  var used,tmp,i,y:longint;
 47  begin
 48  if x=t then exit(f);
 49  tmp:=0;used:=0;
 50  i:=cur[x];
 51  while i<>0 do
 52   begin
 53    y:=e[i].go;
 54    if (h[y]=h[x]+1) and (e[i].v<>0)  then
 55     begin
 56     tmp:=dfs(y,min(f-used,e[i].v));
 57     dec(e[i].v,tmp);
 58     inc(e[i xor 1].v,tmp);
 59     if e[i].v<>0 then cur[x]:=i;
 60     inc(used,tmp);
 61     if used=f then exit(f);
 62     end;
 63    i:=e[i].next;
 64    end;
 65   if used=0 then h[x]:=-1;
 66   exit(used);
 67   end;
 68 procedure dinic;
 69  var i:longint;
 70  begin
 71  ans:=0;
 72  while bfs do
 73   begin
 74    for i:=s to t do cur[i]:=first[i];
 75    inc(ans,dfs(s,inf));
 76   end;
 77  end;
 78 procedure init;
 79  begin
 80  readln(r,c,d);
 81  s:=0;t:=2*r*c+1;cnt:=1;
 82  for i:=1 to r do
 83   for j:=1 to c do
 84    begin
 85     num[i,j,1]:=(i-1)*c+j;
 86     num[i,j,2]:=(i-1)*c+j+r*c;
 87    end;
 88  for i:=1 to r do
 89   begin
 90    for j:=1 to c do read(a[i,j]);
 91    readln;
 92   end;
 93  for i:=1 to r do
 94   for j:=1 to c do
 95    if a[i,j]<>‘0‘ then
 96     begin
 97      insert(num[i,j,1],num[i,j,2],ord(a[i,j])-48);
 98      if (i-d<1) or (i+d>r) or (j-d<1) or (j+d>c)  then insert(num[i,j,2],t,inf)
 99      else
100       begin
101      for k:=i-d to i+d do
102       for l:=j-d to j+d do
103        if sqr(abs(k-i))+sqr(abs(l-j))<=sqr(d) then insert(num[i,j,2],num[k,l,1],inf);
104       end;
105     end;
106  tot:=0;
107  for i:=1 to r do
108   begin
109    for j:=1 to c do
110     begin
111     read(ch);
112     if ch<>‘.‘ then
113      begin
114       inc(tot);
115       insert(s,num[i,j,1],1);
116      end;
117     end;
118    readln;
119   end;
120  end;
121 procedure main;
122  begin
123  dinic;
124  writeln(tot-ans);
125  end;
126 begin
127  init;
128  main;
129 end.

SCOI2007蜥蜴,布布扣,bubuko.com

时间: 2024-08-10 17:11:16

SCOI2007蜥蜴的相关文章

【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流

[bzoj1066]: [SCOI2007]蜥蜴 把石柱拆点,流量为高度 然后S与蜥蜴连流量1的边 互相能跳到的石柱连inf的边 石柱能到边界外的和T连inf的边 然后跑dinic就好了 1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <al

bzoj1066[SCOI2007]蜥蜴

bzoj1066[SCOI2007]蜥蜴 题意: r行c列网格图上有一些高低不平的柱子,一些柱子上有蜥蜴,一只蜥蜴一次能跳距离为d,每次蜥蜴跳跃时出发柱子高度减一,当柱子高度为0时消失,问最少多少蜥蜴不能跳出网格图.r,c≤20,d≤4 题解: 裸最大流,每个柱子拆成X,Y两点,两点之间连柱子的高度,所有Yi向可达柱子的Xi连边,s向所有蜥蜴初始位置连边,所有可以跳出图的柱子向t连边. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #

【bzoj1066】[SCOI2007]蜥蜴 网络最大流

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

[BZOJ1066][luogu_P2472][SCOI2007]蜥蜴

[BZOJ1066][luogu_P2472][SCOI2007]蜥蜴 试题描述 在一个 \(r\) 行 \(c\) 列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为 \(1\),蜥蜴的跳跃距离是 \(d\),即蜥蜴可以跳到平面距离不超过 \(d\) 的任何一个石柱上.石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减 \(1\)(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为 \(1\),则蜥蜴离开

[SCOI2007] 蜥蜴 (最大流)

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

P2472 [SCOI2007]蜥蜴(网络流)

P2472 [SCOI2007]蜥蜴 把每个点拆成2个点,两点之间连边的边权为石柱高度 新建虚拟源点$S$和汇点$T$ $S$向所有有蜥蜴的点连边,边权1 其他边都连$inf$ 剩下就是裸的$dinic$辣 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 200005 inline int Min(int

题解 P2472 【[SCOI2007]蜥蜴】

题目链接 Solution [SCOI2007]蜥蜴 题目大意:给定一个\(n\)行\(m\)列的地图,每个点有一个经过次数限制,可以从一个点跳到与它距离不超过\(d\)的另一个点.问有多少只蜥蜴不能从地图中出去 题目分析:有多少只蜥蜴不能从地图中出去,可以转化成最多有多少只蜥蜴可以从地图中出去.然后从一个点跳到另一个点我们自然而然想到连有向边,每个点的经过次数限制可以看做是流量上限.最多有多少只蜥蜴可以出去,就是求最大流量.这不就是一个最大流么.然后我们来看核心--建图 首先,普通的最大流问题

[BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】

题目链接:BZOJ - 1066 题目分析 题目限制了高度为 x 的石柱最多可以有 x 只蜥蜴从上面跳起,那么就可以用网络流中的边的容量来限制.我们把每个石柱看作一个点,每个点拆成 i1, i2,从 i1 到 i2 连一条边,容量为这个石柱 i 的高度,即跳跃次数限制.来到这个石柱就是向 i1 连边,从这个石柱跳起就是从 i2 向外连边,这样只要从石柱 i 跳起就一定会消耗 i1 到 i2 的边的容量.如果 i 有蜥蜴,就从 S 到 i1 连一条容量为 1 的边,如果从石柱 i 能跳出边界,就从

【BZOJ 1066】[SCOI2007]蜥蜴

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