BZOJ1066
网络流。
坐标为(i,j)的石柱编号为(i-1)*m+j
源点到所有有蜥蜴的石柱建一条容量为1的边,表示一开始就有蜥蜴被石柱生出来。
所有的石柱拆成入点和出点,之间连一条容量为石柱高度的边,达到限流的目的。
石柱的出点连到所有与它平面距离小于d的石柱入点,容量无限。(无数只蜥蜴在空中跨越而过)
若在一个石柱能跳出地图,则让它连到汇点,容量为无限。(无数只蜥蜴掉入深坑)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define min(u1,u2) (u1<u2?u1:u2)
struct mod{int x,y,c,next,other;};
mod q[500000];
int len=0;
int map[25][25];
bool live[25][25];
char s[25];
int first[50000];
int h[50000];
int t[50000];
int S,T,nm,tot=0;
void ins(int x,int y,int c)
{
len++;
q[len].x=x;
q[len].y=y;
q[len].c=c;
q[len].next=first[x];
first[x]=len;
q[len].other=len+1;
len++;
q[len].x=y;
q[len].y=x;
q[len].c=0;
q[len].next=first[y];
first[y]=len;
q[len].other=len-1;
}
bool set_h()
{
int st=1,ed=2;
memset(h,0,sizeof(h));
h[S]=1;
t[1]=S;
while(st<ed)
{
int x=t[st];
//printf("x:%d\n",x);
for (int i=first[x];i!=-1;i=q[i].next)
{
int y=q[i].y;
//printf("y:%d\n",y);
if (q[i].c>0&&h[y]==0)
{
h[y]=h[x]+1;
t[ed]=y;
ed++;
}
}
st++;
}
if (h[T]>0)return true;
return false;
}
int find(int x,int f)
{
if (x==T)return f;
int s=0,o;
for (int i=first[x];i!=-1;i=q[i].next)
{
int y=q[i].y;
if (q[i].c>0&&h[y]==h[x]+1&&s<f)
{
o=find(y,min(q[i].c,f-s));
s+=o;
q[i].c-=o;
q[q[i].other].c+=o;
}
}
if (s==0)h[x]=0;
return s;
}
int main()
{
int n,m,d;
memset(first,-1,sizeof(first));
scanf("%d%d%d",&n,&m,&d);
nm=n*m;
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
for (int j=1;j<=m;j++)
{
map[i][j]=s[j]-'0';
}
}
memset(live,false,sizeof(live));
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
for (int j=1;j<=m;j++)
{
if (s[j]=='L')
{
live[i][j]=true;
tot++;
}
}
}
S=0,T=nm*3+1;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
if (live[i][j])
ins(S,(i-1)*m+j,1);
if (map[i][j]>0)
ins((i-1)*m+j,(i-1)*m+j+nm,map[i][j]);
else
continue;
for (int soyx=1;soyx<=n;soyx++)
for (int soyy=1;soyy<=m;soyy++)
{
if (map[soyx][soyy]==0)continue;
if (i==soyx&&j==soyy)continue;
if (d*d>=(i-soyx)*(i-soyx)+(j-soyy)*(j-soyy))
ins((i-1)*m+j+nm,(soyx-1)*m+soyy,999999999);
}
if (i<=d||i+d>n||j<=d||j+d>m)
ins((i-1)*m+j+nm,T,999999999);
}
//for (int i=1;i<=len;i++)
//printf("i:%d x:%d y:%d c:%d\n",i,q[i].x,q[i].y,q[i].c);
int ans=0;
while(set_h()==true)
{
//system("pause");
ans+=find(S,999999999);
}
printf("%d\n",tot-ans);
}