您的位置:首页 > 理论基础 > 计算机网络

BZOJ 1066 Dinic

2016-12-09 20:59 295 查看
思路:

网络流 建边比较麻烦

//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 100050
int r,c,d,n=66666,tmp;
char a[105][105],b[105][105];
struct Dinic{
int first
,next
,v
,w
,tot,vis
;
void add(int x,int y,int z){Add(x,y,z),Add(y,x,0);}
void Add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void init(){
memset(first,-1,sizeof(first));
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++){
if(b[i][j]=='L')add(0,(i*c+j)*2,1),tmp++;
if(a[i][j]!='0')add((i*c+j)*2,(i*c+j)*2+1,a[i][j]-'0');
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++){
if(a[i][j]=='0')continue;
for(int k=1;k<=r;k++)
for(int l=1;l<=c;l++){
if(a[k][l]=='0'||(i==k&&j==l))continue;
if((i-k)*(i-k)+(j-l)*(j-l)<=d*d)
add((i*c+j)*2+1,(k*c+l)*2,0x3fffff);
}
}
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
if((i-1<d||j-1<d||r-i<d||c-j<d)&&a[i][j]!='0')add((i*c+j)*2+1,n,0x3fffff);
}
}
flow();
}
bool tell(){
queue<int>q;q.push(0);
memset(vis,-1,sizeof(vis));vis[0]=0;
while(!q.empty()){
int t=q.front();q.pop();
for(int i=first[t];~i;i=next[i])
if(vis[v[i]]==-1&&w[i])
q.push(v[i]),vis[v[i]]=vis[t]+1;
}
return vis
!=-1;
}
int zeng(int x,int y){
if(x==n)return y;
int r=0;
for(int i=first[x];y>r&&~i;i=next[i])
if(w[i]&&vis[v[i]]==vis[x]+1){
int t=zeng(v[i],min(y-r,w[i]));
w[i]-=t,w[i^1]+=t,r+=t;
}
if(!r)vis[x]=-1;
return r;
}
void flow(){
int ans=0,jy;
while(tell())while(jy=zeng(0,0x3ffffff))ans+=jy;
printf("%d\n",tmp-ans);
}
}dinic;
int main(){
scanf("%d%d%d",&r,&c,&d);
for(int i=1;i<=r;i++)scanf("%s",a[i]+1);
for(int i=1;i<=r;i++)scanf("%s",b[i]+1);
dinic.init();
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  namespace 网络