题目描述
在一个r行c列的网络地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。
每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。
题目大意
题目大意
数据范围
数据范围
样例输入
5 8 2
00000000
02000000
00321100
02000000
00000000
. . . . . . . .
. . . . . . . .
. . L L L L . .
. . . . . . . .
. . . . . . . .
样例输出
1
解题思路
拆点,如果一个点能跳向另一个点则前一个点的出点,向第二个点的入点连边。
如果能跳出边界则出点向T连边。
如果起始为蜥蜴则S向入点连边。
答案则为蜥蜴总数-最大流。
代码
#include <bits/stdc++.h>
#define Maxn 233333
#define Maxe 233333
#define ha(x,y) (((x)-1)*c+(y))
using namespace std;
inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
inline int Getval(){char ch=getchar();while(!isdigit(ch))ch=getchar();return ch-'0';}
inline char Getch(){char ch=getchar();while(ch!='.'&&ch!='L')ch=getchar();return ch;}
int S,T,N,cnt=0,dis[Maxn],GAP[Maxn],h[Maxn],vl[25][25],r,c,d;
struct node{int to,next,v,pair;}e[Maxe];
void AddEdge(int x,int y,int v,int pair){e[cnt]=(node){y,h[x],v,pair};h[x]=cnt;}
void AddEdge(int x,int y,int v){AddEdge(x,y,v,++cnt+1);AddEdge(y,x,0,++cnt-1);}
int GetDis(int x,int y,int xx,int yy){return (x-xx)*(x-xx)+(y-yy)*(y-yy);}
int SAP(int x,int Maxflow){
if(x==T)return Maxflow;
int tmp=Maxflow;
for(int p=h[x];p;p=e[p].next){
int y=e[p].to;
int flow=min(e[p].v,tmp);
if(flow&&dis[x]==dis[y]+1){
int ret=SAP(y,flow);
tmp-=ret;
e[p].v-=ret;
e[e[p].pair].v+=ret;
if(!tmp||dis[S]==N)return Maxflow-tmp;
}
}
if(--GAP[dis[x]]==0)dis[S]=N;
else GAP[++dis[x]]++;
return Maxflow-tmp;
}
int SAP(){
memset(GAP,0,sizeof(GAP));
memset(dis,0,sizeof(dis));
GAP[0]=N;
int Ans=0;
while(dis[S]<N)Ans+=SAP(S,1<<30);
return Ans;
}
int main(){
r=Getint(),c=Getint(),d=Getint();
int tot=0;
S=0,T=r*c*2+1,N=T+1;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
vl[i][j]=Getval();
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
if(vl[i][j])
AddEdge(ha(i,j),ha(i,j)+r*c,vl[i][j]);
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
if(Getch()=='L')
AddEdge(S,ha(i,j),1),tot++;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++){
if(!vl[i][j])continue;
if(i<=d||j<=d||(r-i+1)<=d||(c-j+1)<=d)
AddEdge(ha(i,j)+r*c,T,1<<30);
for(int i1=1;i1<=r;i1++)
for(int j1=1;j1<=c;j1++)
if((!(i==i1&&j==j1))&&vl[i1][j1]&&GetDis(i,j,i1,j1)<=d*d)
AddEdge(ha(i,j)+r*c,ha(i1,j1),1<<30);
}
cout<<tot-SAP();
return 0;
}