Description
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
石柱上。
Input
输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。
Output
输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。
Sample Input
5 8 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
Sample Output
1
HINT
100%的数据满足:1<=r, c<=20, 1<=d<=4
Source
网络流
对于每根柱子 将它拆成两个点(可以理解为柱子下和柱子上) 流量为高度
这样点流量就转为了边流量
<span style="font-size:18px;">#include<bits/stdc++.h>
using namespace std;
const int inf=1e9+7;
const int maxn=200020;
int r,c,d,cnt=1,ans;
char ch[21];
int mp[21][21],mark[21][21],head[802],q[802],dis[802];
struct edge
{
int to,nxt,flow;
}e[maxn];
inline void addedge(int x,int y,int fl)
{
e[++cnt].to=y;
e[cnt].nxt=head[x];
head[x]=cnt;
e[cnt].flow=fl;
e[++cnt].to=x;
e[cnt].nxt=head[y];
head[y]=cnt;
e[cnt].flow=0;
}
bool judge(int x1,int y1,int x2,int y2)
{
if(mp[x1][y1]&&mp[x2][y2]&&(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)<=d*d)
return true;
return false;
}
inline bool bfs()
{
int ql=0,qr=1;
q[1]=0;
memset(dis,0,sizeof(dis));
dis[0]=1;
while(ql<qr)
{
int x=q[++ql];
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(e[i].flow&&!dis[y])
{
dis[y]=dis[x]+1;
q[++qr]=y;
}
}
}
if(dis[801]) return true;
return false;
}
inline int dfs(int x,int flow)
{
if(x==801) return flow;
int d,used=0;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(e[i].flow&&dis[y]==dis[x]+1)
{
d=dfs(y,min(flow,e[i].flow));
e[i].flow-=d;
e[i^1].flow+=d;
used+=d;
if(used==flow)
return flow;
}
}
if(!used)
dis[x]=-1;
return used;
}
inline void dinic()
{
while(bfs())
ans-=dfs(0,inf);
}
int main()
{
scanf("%d%d%d",&r,&c,&d);
for(int i=1;i<=r;i++)
{
scanf("%s",ch);
for(int j=0;j<c;j++)
mp[i][j+1]=ch[j]-'0';
}
int tot=0;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
mark[i][j]=++tot;
for(int i=1;i<=r;i++)
{
scanf("%s",ch);
for(int j=0;j<c;j++)
if(ch[j]=='L')
ans++,addedge(0,mark[i][j+1],1);
}
for(int i=1;i<=d;i++)
for(int j=d+1;j<=r-d;j++)
{
addedge(mark[j][i]+400,801,inf);
addedge(mark[j][c-i+1]+400,801,inf);
}
for(int i=1;i<=d;i++)
for(int j=1;j<=c;j++)
{
addedge(mark[i][j]+400,801,inf);
addedge(mark[r-i+1][j]+400,801,inf);
}
for(int x1=1;x1<=r;x1++)
{
for(int y1=1;y1<=c;y1++)
{
for(int x2=x1-d;x2<=x1+d;x2++)
{
for(int y2=y1-d;y2<=y1+d;y2++)
{
if(judge(x1,y1,x2,y2)&&(x1!=x2||y1!=y2))
{
addedge(mark[x1][y1]+400,mark[x2][y2],inf);
}
}
}
}
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
if(mp[i][j])
addedge(mark[i][j],mark[i][j]+400,mp[i][j]);
dinic();
cout<<ans;
}</span>