题目大意:告诉你一个网格状的地图,每个点上都有柱子,有些柱子上有蜥蜴,然后每个柱子有寿命,当一个蜥蜴跳到这个柱子上再跳走后,这个柱子寿命减1,问你最后有几个蜥蜴不能活着离开,既然每个柱子有寿命,就可以用拆点来做,来限制经过这个柱子的蜥蜴数量。题目告诉了你蜥蜴最大的跳跃距离,在跳跃范围之内,只要柱子的寿命不是0,活着柱子上没其他蜥蜴,就能跳,然后求最大流,用总的蜥蜴数量减去求出来的最大流,就是牺牲的蜥蜴。
emmm,建图的时候我参考了这个博客:https://blog.csdn.net/nmfloat/article/details/46765269
最后放上我的AC代码
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static class edge{
int v,next,c;
edge(int v,int next,int c){
this.v=v;
this.next=next;
this.c=c;
}
}
static final int inf=0x3f3f3f3f;
static final int maxn=100010;
static final int maxe=400010;
static edge e[]=new edge[maxe];
static int p[]=new int[maxn];
static int n,m,eid,S,T;
static void init(){
Arrays.fill(p, -1);
eid=0;
}
static void insert(int u,int v,int c){
e[eid]=new edge(v,p[u],c);
p[u]=eid++;
}
static void add(int u,int v,int c){
insert(u,v,c);
insert(v,u,0);
}
static int d[]=new int[maxn];
static boolean bfs(){
Arrays.fill(d, -1);
Queue<Integer> q=new LinkedList<Integer>();
q.add(S);
d[S]=0;
while(!q.isEmpty()){
int u=q.poll();
for(int i=p[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(e[i].c>0&&d[v]==-1){
d[v]=d[u]+1;
q.add(v);
}
}
}
return d[T]!=-1;
}
static int dfs(int u,int flow){
if(u==T)
return flow;
int res=0;
for(int i=p[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(e[i].c>0&&d[u]+1==d[v]){
int tmp=dfs(v,Math.min(e[i].c,flow));
e[i].c-=tmp;
flow-=tmp;
res+=tmp;
e[i^1].c+=tmp;
if(flow==0){
break;
}
}
}
if(res==0){
d[u]=-1;
}
return res;
}
static int dinic(){
int res=0;
while(bfs()){
res+=dfs(S,inf);
}
return res;
}
static boolean isin(int x,int y){
return x>=0&&x<=n&&y>=0&&y<=m;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
int cnt=0;
while(t-->0){
cnt++;
int dis;
n=sc.nextInt();
dis=sc.nextInt();
int map1[][]=new int[25][25];
char map2[][]=new char[25][25];
int mat[][]=new int[25][25];
init();
sc.nextLine();
int len=0;
int tot=0;
for(int i=0;i<n;i++){
String s=sc.nextLine();
len=s.length();
for(int j=0;j<s.length();j++){
map1[i][j]=Integer.valueOf(s.charAt(j)-'0');
if(map1[i][j]>0){
mat[i][j]=++tot;
add(tot*2-1,tot*2,map1[i][j]);
}
}
}
int num=0;
m=len;
S=0;
T=tot*2+1;
for(int i=0;i<n;i++){
String s=sc.nextLine();
for(int j=0;j<s.length();j++){
map2[i][j]=s.charAt(j);
if(map2[i][j]=='L'){
num++;
add(S,mat[i][j]*2-1,1);
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(mat[i][j]!=0){
for(int x=(-1)*dis;x<=dis;x++){
for(int y=Math.abs(x)-dis;y<=dis-Math.abs(x);y++){
if(isin(i+x,j+y)&&mat[i+x][j+y]!=0
&&(x!=0||y!=0)){
add(mat[i][j]*2,mat[i+x][j+y]*2-1,inf);
}
}
}
if(i<dis||j<dis||n-i<=dis||m-j<=dis){
add(mat[i][j]*2,T,inf);
}
}
}
}
int res=dinic();
if(num-res==0)
System.out.println("Case #"+cnt+": no lizard was left behind.");
else if(num-res>1)
System.out.println("Case #"+cnt+": "+(num-res)+" lizards were left behind.");
else
System.out.println("Case #"+cnt+": "+(num-res)+" lizard was left behind.");
}
sc.close();
}
}