您的位置:首页 > 其它

bzoj 1066: [SCOI2007]蜥蜴

2016-03-01 22:42 351 查看
#include<cstdio>
#include<iostream>
#define T 1001
#define M 10005
#define inf 0x7fffffff
#include<cstring>
using namespace std;
int cnt=1,r,c,d,head[M],next[10*M],u[10*M],v[10*M],sum,f[25][25],d1[M],q[M],ans;
char ch[50];
int S(int a1,int a2)
{
return (a1-1)*c+a2;
}
void jia(int a1,int a2,int a3)
{
cnt++;
u[cnt]=a2;
v[cnt]=a3;
next[cnt]=head[a1];
head[a1]=cnt;
return;
}
bool pan(int a1,int a2,int a3,int a4)
{
if(a1==a3&&a2==a4)
return 0;
if((a1-a3)*(a1-a3)+(a2-a4)*(a2-a4)>d*d)
return 0;
if(!f[a3][a4])
return 0;
return 1;
}
bool bfs()
{
memset(d1,0,sizeof(int)*M);
int h=0,t=1;
q[1]=0;
d1[0]=1;
for(;h<t;)
{
h++;
int p=q[h];
for(int i=head[p];i;i=next[i])
if(!d1[u[i]]&&v[i])
{
d1[u[i]]=d1[p]+1;
if(d1[T])
return 1;
t++;
q[t]=u[i];
}
}
return 0;
}
int dinic(int s,int f)
{
if(s==T)
return f;
int rest=f;
for(int i=head[s];i&&rest;i=next[i])
if(v[i]&&d1[u[i]]==d1[s]+1)
{
int now=dinic(u[i],min(rest,v[i]));
if(!now)
d1[u[i]]=0;
v[i]-=now;
v[i^1]+=now;
rest-=now;
}
return f-rest;
}
int main()
{
scanf("%d%d%d",&r,&c,&d);
for(int i=1;i<=r;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=c;j++)
{
int a1=ch[j]-'0';
if(a1)
{
f[i][j]=1;
jia(S(i,j),S(i,j)+r*c,a1);
jia(S(i,j)+r*c,S(i,j),0);
}
}
}
for(int i=1;i<=r;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=c;j++)
if(ch[j]=='L')
{
jia(0,S(i,j),1);
jia(S(i,j),0,0);
sum++;
}
}
for(int i=1;i<=d;i++)
for(int j=d+1;j<=r-d;j++)
{
jia(S(j,i)+r*c,T,inf);
jia(T,S(j,i)+r*c,0);
jia(S(j,c-i+1)+r*c,T,inf);
jia(T,S(j,c-i+1),0);
}
for(int i=1;i<=d;i++)
for(int j=1;j<=c;j++)
{
jia(S(i,j)+r*c,T,inf);
jia(T,S(i,j),0);
jia(S(r-i+1,j)+r*c,T,inf);
jia(T,S(r-i+1,j),0);
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
if(f[i][j])
for(int x=i-d;x<=i+d;x++)
for(int y=j-d;y<=j+d;y++)
if(pan(i,j,x,y))
{
jia(S(i,j)+r*c,S(x,y),inf);
jia(S(x,y),S(i,j)+r*c,0);
}
while(bfs())
sum-=dinic(0,0x7fffffff);
printf("%d\n",sum);
return 0;
}


这是一个建图极其恶心的网络流 拆点 xi,xj。每个有石柱地方xi,xj,高。‘L'出S,xi,1;能跳出去的地方建边,能互相跳的石柱建边。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: