Leapin' Lizards
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2185 Accepted Submission(s): 910
Problem Description
Your platoon of wandering lizards has entered a strange room in the labyrinth you are exploring. As you are looking around for hidden treasures, one of the rookies steps on an innocent-looking stone and the room's floor suddenly disappears!
Each lizard in your platoon is left standing on a fragile-looking pillar, and a fire begins to rage below... Leave no lizard behind! Get as many lizards as possible out of the room, and report the number of casualties.
The pillars in the room are aligned as a grid, with each pillar one unit away from the pillars to its east, west, north and south. Pillars at the edge of the grid are one unit away from the edge of the room (safety). Not all pillars necessarily have a lizard. A lizard is able to leap onto any unoccupied pillar that is within d units of his current one. A lizard standing on a pillar within leaping distance of the edge of the room may always leap to safety... but there's a catch: each pillar becomes weakened after each jump, and will soon collapse and no longer be usable by other lizards. Leaping onto a pillar does not cause it to weaken or collapse; only leaping off of it causes it to weaken and eventually collapse. Only one lizard may be on a pillar at any given time.
The pillars in the room are aligned as a grid, with each pillar one unit away from the pillars to its east, west, north and south. Pillars at the edge of the grid are one unit away from the edge of the room (safety). Not all pillars necessarily have a lizard. A lizard is able to leap onto any unoccupied pillar that is within d units of his current one. A lizard standing on a pillar within leaping distance of the edge of the room may always leap to safety... but there's a catch: each pillar becomes weakened after each jump, and will soon collapse and no longer be usable by other lizards. Leaping onto a pillar does not cause it to weaken or collapse; only leaping off of it causes it to weaken and eventually collapse. Only one lizard may be on a pillar at any given time.
Input
The input file will begin with a line containing a single integer representing the number of test cases, which is at most 25. Each test case will begin with a line containing a single positive integer n representing the number of
rows in the map, followed by a single non-negative integer d representing the maximum leaping distance for the lizards. Two maps will follow, each as a map of characters with one row per line. The first map will contain a digit (0-3) in each position representing
the number of jumps the pillar in that position will sustain before collapsing (0 means there is no pillar there). The second map will follow, with an 'L' for every position where a lizard is on the pillar and a '.' for every empty pillar. There will never
be a lizard on a position where there is no pillar.Each input map is guaranteed to be a rectangle of size n x m, where 1 ≤ n ≤ 20 and 1 ≤ m ≤ 20. The leaping distance is
always 1 ≤ d ≤ 3.
always 1 ≤ d ≤ 3.
Output
For each input case, print a single line containing the number of lizards that could not escape. The format should follow the samples provided below.
Sample Input
4
3 1
1111
1111
1111
LLLL
LLLL
LLLL
3 2
00000
01110
00000
.....
.LLL.
.....
3 1
00000
01110
00000
.....
.LLL.
.....
5 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
3 1
1111
1111
1111
LLLL
LLLL
LLLL
3 2
00000
01110
00000
.....
.LLL.
.....
3 1
00000
01110
00000
.....
.LLL.
.....
5 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
Sample Output
Case #1: 2 lizards were left behind.Case #2: no lizard was left behind.
Case #3: 3 lizards were left behind.
Case #4: 1 lizard was left behind.
题目大意:
每组数据先输入两个数,第一个表示一共有n行,第二个表示蜥蜴一步能够跳多远。
然后输入n行,表示每个点上边有多少柱子,接下来再输入n行,表示当前情况,L表示有一只蜥蜴。问最少能够留下多少只蜥蜴。(被困住)。保证有L的地方就有柱子,蜥蜴每一次跳跃会摧毁本地一根柱子。
思路:
1、能够逃离的最多蜥蜴就是最大的流量。
2、设定第一行第一列的点编号为0,设定第n行,第m列编号为n*m-1,设定源点s为n*m,设定汇点t为n*m+1
3、点容量,转化成边容量,需要拆点,一分为二。将点i拆成点i和点i+pie。源点和汇点不需要拆点。然后将点i到点i+pie的容量定为其点容量的值。【pie==n*m+2】
4、建图:源点s到有蜥蜴的点容量设为1.然后如果能从一个点u跳到点v(此处我用Bfs来判定的),那么连接有向边:u+pie,v,并且设定其容量为INF。
5、跑一遍Edmond-Karp算法,求最大流。
6、对应输出,注意,这块如果是剩下一只蜥蜴,要输出单数,否则输出复数。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node
{
int x,y,step;
}now,nex;
int pre[1050];
int map[1050][1050];
char aa[1050][1050];
char a[1050][1050];
int vis[50][50];
int flag[1050];
int fx[4]={0,0,1,-1};
int fy[4]={1,-1,0,0};
int n,m,q;
int s,t;
int pie,kase;
int Ek_Bfs(int ss,int tt)
{
queue<int >s;
memset(flag,0,sizeof(flag));
memset(pre,-1,sizeof(pre));
s.push(ss);
flag[ss]=1;
while(!s.empty())
{
int u=s.front();
//printf("%d\n",u);
s.pop();
if(u==tt)return 1;
for(int i=0;i<n*m+2+pie;i++)
{
if(map[u][i]&&flag[i]==0)
{
flag[i]=1;
pre[i]=u;
s.push(i);
}
}
}
return 0;
}
void Bfs(int u,int x,int y)
{
queue<node>s;
memset(vis,0,sizeof(vis));
now.x=x;now.y=y;now.step=0;
s.push(now);vis[now.x][now.y]=1;
while(!s.empty())
{
now=s.front();s.pop();
for(int i=0;i<4;i++)
{
nex.x=now.x+fx[i];
nex.y=now.y+fy[i];
nex.step=now.step+1;
if(nex.step>q)continue;
if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m)
{
if(vis[nex.x][nex.y]==0)
{
if(aa[nex.x][nex.y]!='0')
{
map[u][nex.x*m+nex.y]=0x3f3f3f3f;
}
vis[nex.x][nex.y]=1;
s.push(nex);
}
}
else
{
map[u][t]=0x3f3f3f3f;
}
}
}
}
void getmap()
{
memset(map,0,sizeof(map));
s=n*m,t=n*m+1;
pie=n*m+2;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i][j]=='L')
{
map[s][i*m+j]+=1;
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
map[i*m+j][i*m+j+pie]=aa[i][j]-'0';
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(aa[i][j]!='0')
Bfs(i*m+j+pie,i,j);
}
}
/*
for(int i=0;i<n*m+pie;i++)
{
for(int j=0;j<n*m+pie;j++)
{
if(map[i][j]==0x3f3f3f3f)
{
printf("%d %d -1\n",i,j);
}
else if(map[i][j]!=0)
printf("%d %d %d\n",i,j,map[i][j]);
}
}
*/
}
void Edmond_Karp()
{
int u,maxflow=0,mn;
while(Ek_Bfs(s,t))
{
mn=0x3f3f3f3f;
u=t;
while(pre[u]!=-1)
{
mn=min(mn,map[pre[u]][u]);
u=pre[u];
}
maxflow+=mn;
u=t;
while(pre[u]!=-1)
{
map[pre[u]][u]-=mn;
map[u][pre[u]]+=mn;
u=pre[u];
}
}
int contz=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i][j]=='L')contz++;
}
}
int ans=contz-maxflow;
if(ans==0)
printf("Case #%d: no lizard was left behind.\n",++kase);
else if(ans==1)
printf("Case #%d: 1 lizard was left behind.\n",++kase);
else printf("Case #%d: %d lizards were left behind.\n",++kase,ans);
}
int main()
{
int t;
kase=0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
for(int i=0;i<n;i++)
{
scanf("%s",aa[i]);
}
for(int i=0;i<n;i++)
{
scanf("%s",&a[i]);
}
m=strlen(a[0]);
getmap();
Edmond_Karp();
}
}