标签:
给你两个图,一个用0,1,2,3表示,一个用 L 或 . 表示。其中用L表示的图中,有L的位置表示有蜥蜴,没有L的位置表示没有蜥蜴。用数字表示的图中,数字表示当前位置柱子的高度,每次一个蜥蜴可以从一个柱子跳到距离d以内的另外一个柱子,每跳跃一次,当前柱子的高度就减一,问最后会有多少只蜥蜴被困在里面。
首先,可以明显的看到,一个柱子是有固定的通过次数的,这一点跟网络流中边的属性很像,但是这里的柱子是点,并不是边,对于这样的情况,在这里我们采用拆点的方法
把一根柱子拆成两个点,一条边,从第一个点向第二个点连一条有向边,权为这个柱子的高度,在从第二个点向所有能到达的其他柱子构造一条边,权可以设为无穷(一定可通过)。最后,能跳出的点连向汇点,构造源点向所有有蜥蜴的点连一条权为1的边。至此,构图完毕。
解法即是在以上图上做一遍最大流,即可得到解。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define INF 0x7fffffff;
using namespace std;
int T,n,d,a[1005][1005],flow[1005],pre[1005],q[1005],node[25][25];
char s[25][25];
int bfs(int s,int des,int k)
{
int h=0,t=0;
memset(q,0,sizeof(q));
memset(pre,0,sizeof(pre));
q[h++]=s; pre[s]=s; flow[s]=INF; flow[des]=0;
while (h!=t)
{
int u=q[t];
if (u==des) break;
for (int v=1;v<=k;v++) if (a[u][v]>0 && !pre[v])
{
pre[v]=u; q[h++]=v;
flow[v]=min(flow[u],a[u][v]);
}
t++;
}
if (pre[des]==0) return 0;
else return flow[des];
}
int maxflow(int s,int des,int k)
{
int t,ans=0;
while (t=bfs(s,des,k),t!=0)
{
for (int i=des;i!=s;i=pre[i])
{
a[pre[i]][i]-=t;
a[i][pre[i]]+=t;
}
ans+=t;
}
return ans;
}
int main()
{
int Case=1;
scanf("%d",&T);
while (T--)
{
memset(flow,0,sizeof(flow));
memset(a,0,sizeof(a));
memset(node,0,sizeof(node));
memset(s,0,sizeof(s));
scanf("%d%d",&n,&d);
for (int i=0;i<n;i++) scanf("%s",&s[i]);
int m=strlen(s[0]),t=2;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++) if (s[i][j]!=‘0‘)
{
node[i][j]=t;
a[t][t+1]=s[i][j]-‘0‘;
t+=2;
}
for (int i=0;i<n;i++)
for (int j=0;j<m;j++) if (s[i][j]!=‘0‘ && (i+1<=d || j+1<=d || n-i<=d || m-j<=d)) a[node[i][j]+1][t]=INF;
for (int i1=0;i1<n;i1++)
for (int j1=0;j1<m;j1++)
for (int i2=0;i2<n;i2++)
for (int j2=0;j2<m;j2++)
if (s[i1][j1]!=‘0‘ && s[i2][j2]!=0 && abs(i1-i2)+abs(j1-j2)<=d)
{
//node[i1][j1]+1->node[i2][j2]
a[node[i1][j1]+1][node[i2][j2]]=INF;
}
for (int i=0;i<n;i++) scanf("%s",&s[i]);
int l=0;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++) if (s[i][j]==‘L‘)
{
if (node[i][j]) a[1][node[i][j]]=1;
l++;
}
int ans=l-maxflow(1,t,t);
printf("Case #%d: ",Case++);
if (ans==0) printf("no lizard was left behind.\n");
else if (ans==1) printf("1 lizard was left behind.\n");
else if (ans>=2) printf("%d lizards were left behind.\n",ans);
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/s_black/article/details/51332597