Description
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。
Input
输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。
Output
输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。
最大流
每条石柱拆成两个点,连边容量为石柱高度
在距离不超过d的石柱间连边,容量为inf
从源点连边到每条有蜥蜴的石柱,容量为1
从可以跳到图外的点连边到汇点,容量为inf
#include<cstdio> #include<cstring> struct edge{ int nx,w; edge(){} edge(int a,int b){ nx=a; w=b; } }es[100005]; int ep=2; const int S=0,T=1,INF=2147483647; int g[100005][2],gp=1005; int h[10005]; int v[105][105]; int q[10005]; int n,m,ans=0,mx,ls=0; int ids[24][24],idp=2; int hs[24][24]; char c; inline int min(int a,int b){return a<b?a:b;} inline void addedge(int s,int t,int w){ es[ep]=edge(t,w); g[gp][0]=ep++; g[gp][1]=g[s][1]; g[s][1]=gp++; es[ep]=edge(s,0); g[gp][0]=ep++; g[gp][1]=g[t][1]; g[t][1]=gp++; } inline bool bfs(){ int qs=0,qe=0; q[qe++]=S; memset(h,-1,sizeof h); h[S]=0; while(qs<qe){ int w=q[qs++]; int i=w; while(i=g[i][1]){ int e=g[i][0]; int u=es[e].nx; if(h[u]!=-1||!es[e].w)continue; h[u]=h[w]+1; q[qe++]=u; } } return h[T]!=-1; } int dfs(int w,int f){ if(w==T)return f; int i=w; int used=0,c; while(i=g[i][1]){ int e=g[i][0]; int u=es[e].nx; if(h[u]!=h[w]+1||es[e].w==0)continue; c=f-used; c=dfs(u,min(c,es[e].w)); es[e].w-=c; es[e^1].w+=c; used+=c; if(used==f)return f; } if(!used)h[w]=-1; return used; } char gc(){ char c=getchar(); while((c<'0'||c>'9')&&c!='L'&&c!='.')c=getchar(); return c; } int main(){ scanf("%d%d%d",&n,&m,&mx); for(int i=0;i<n;i++) for(int j=0;j<m;j++) ids[i][j]=idp++; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ c=gc(); hs[i][j]=c-'0'; } } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(hs[i][j]>0){ addedge(ids[i][j],ids[i][j]+n*m,hs[i][j]); bool o=0; for(int x=-mx;x<=mx;x++){ for(int y=-mx;y<=mx;y++){ if(x*x+y*y>mx*mx)continue; if(i+x<0||i+x>=n||j+y<0||j+y>=m){ o=1; continue; } if(hs[i+x][j+y]==0)continue; addedge(ids[i][j]+n*m,ids[i+x][j+y],INF); } } if(o)addedge(ids[i][j]+n*m,T,INF); } } } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ c=gc(); if(c=='L')addedge(S,ids[i][j],1),ls++; } } while(bfs())ans+=dfs(S,INF); printf("%d",ls-ans); return 0; }