题意
给你两个图,一个用0,1,2,3表示,一个用 L 或 . 表示。其中用L表示的图中,有L的位置表示有蜥蜴,没有L的位置表示没有蜥蜴。用数字表示的图中,数字表示当前位置柱子的高度,每次一个蜥蜴可以从一个柱子跳到距离d以内的另外一个柱子,每跳跃一次,当前柱子的高度就减一,问最后会有多少只蜥蜴被困在里面。
解
将柱子拆点,每个蜥蜴向其曼哈顿距离内点连边,跑最大流
代码
#include
#include
#include
#include
#include
#define For(i,j,k) for(int i=(j);i<=(int)k;i++)
#define Forr(i,j,k) for(int i=(j);i>=(int)k;i--)
#define Set(a,b) memset(a,b,sizeof(a))
#define Rep(i,u) for(int i=Begin[u],v=to[i];i;i=Next[i],v=to[i])
using namespace std;
const int N=810,M=7500,INF=0x3f3f3f3f;
template <class T>inline void read(T &x){
x=0;char c=getchar();int f(0);
while(c>'9'||c<'0')f|=(c=='-'),c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
template <class T>inline void chkmin(T &a,T b){a=a>b?b:a;}
template <class T>inline void chkmax(T &a,T b){a=aint Begin[N],Next[M<<1],to[M<<1],f[M<<1],e=1,n,m,d;
inline void add(int x,int y,int z){
to[++e]=y,Next[e]=Begin[x],Begin[x]=e,f[e]=z;
}
struct isap{
int s,t,gap[N],d[N],p[N],cur[N];
#define Retr(u) for(u=t;u^s;u=to[p[u]^1])
inline void init(){
queue<int>q;
For(i,1,t)d[i]=INF,gap[i]=0,cur[i]=Begin[i];
gap[0]=1;d[t]=0;q.push(t);
while(!q.empty()){
int r=q.front();q.pop();
Rep(i,r)
if(f[i^1]&&d[v]>d[r]+1)
++gap[d[v]=d[r]+1],q.push(v);
}
}
inline int Augment(){
int u,a=INF;
Retr(u)chkmin(a,f[p[u]]);
Retr(u)f[p[u]]-=a,f[p[u]^1]+=a;
return a;
}
inline int Maxflow(int _s,int _t){
int i,u=s=_s,flow=0;t=_t;
init();
while(d[s]if(u==t)flow+=Augment(),u=s;
for(i=cur[u];i;i=Next[i])
if(f[i]&&d[u]==d[to[i]]+1)break;
if(!i){
if(--gap[d[u]]==0)break;
d[u]=t;cur[u]=Begin[u];
Rep(i,u)
if(f[i])chkmin(d[u],d[v]+1);
++gap[d[u]];
if(u^s)u=to[p[u]^1];
}else cur[u]=i,p[u=to[i]]=i;
}
return flow;
}
}F;
char ch[25];
char st[25][25];
struct node{
int x,y,z;
node(int x=0,int y=0,int z=0):x(x),y(y),z(z){}
}P[N];
inline bool can(node a,node b,int d){
int l=abs(a.x-b.x)+abs(a.y-b.y);
if(l<=d)return 1;
return 0;
}
inline bool out(node a,int d){
return a.x+d>n || a.x-d<1 || a.y+1+d>m || a.y-d<0;
}
inline void work(){
int totz(0),totl(0);
read(n),read(d);
Set(Begin,0),e=1,m=0;
For(i,1,n){
scanf("%s",ch);
if(!m)m=strlen(ch);
For(j,0,m-1)
if(ch[j]!='0')
P[++totz]=node(i,j,ch[j]-'0');
}
For(i,1,n)
scanf("%s",st[i]);
int s_=totz*2+1,t_=s_+1;
For(i,1,totz){
add(i,i+totz,P[i].z),add(i+totz,i,0);
For(j,1,totz)
if(i!=j)
if(can(P[i],P[j],d))
add(i+totz,j,P[i].z),add(j,i+totz,0);
if(st[P[i].x][P[i].y]=='L')add(s_,i,1),add(i,s_,0),totl++;
if(out(P[i],d))add(i+totz,t_,P[i].z),add(t_,i+totz,0);
}
int ans=totl-F.Maxflow(s_,t_);
if(ans==0)
printf("no ");
else printf("%d ",ans);
if(ans==1||ans==0)puts("lizard was left behind.");
else puts("lizards were left behind.");
}
int main(){
int T;
read(T);
For(i,1,T)
printf("Case #%d: ",i),work();
return 0;
}