BZOJ1066: [SCOI2007]蜥蜴

BZOJ1066: [SCOI2007]蜥蜴

https://lydsy.com/JudgeOnline/problem.php?id=1066

分析:

  • 每个格子拆成两个点,中间限制流量为高度。
  • \(S\)向初始位置连边,能走出去的向\(T\)连边。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
#define N 100050
#define S 100048
#define T 100049
#define inf 0x3f3f3f3f
int head[N],to[N],nxt[N],flow[N],cnt=1,n,m,d;
int dep[N],Q[N];
inline void add(int u,int v,int f) {
    to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f;
    to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0;
}
bool bfs() {
    memset(dep,0,sizeof(dep));
    int l=0,r=0; Q[r++]=S; dep[S]=1;
    while(l<r) {
        int x=Q[l++],i;
        for(i=head[x];i;i=nxt[i]) if(flow[i]&&!dep[to[i]]) {
            dep[to[i]]=dep[x]+1;
            if(to[i]==T) return 1;
            Q[r++]=to[i];
        }
    }
    return 0;
}
int dfs(int x,int mf) {
    int i;
    if(x==T) return mf;
    int nf=0;
    for(i=head[x];i;i=nxt[i]) if(flow[i]&&dep[to[i]]==dep[x]+1) {
        int tmp=dfs(to[i],min(mf-nf,flow[i]));
        nf+=tmp;
        flow[i]-=tmp;
        flow[i^1]+=tmp;
        if(!tmp) dep[to[i]]=0;
        if(nf==mf) break;
    }
    return nf;
}
char mp1[25][25],mp2[25][25];
int id[25][25];
int main() {
    scanf("%d%d%d",&n,&m,&d);
    int i,j,k,l;
    for(i=1;i<=n;i++)for(j=1;j<=m;j++)id[i][j]=++id[0][0];
    for(i=1;i<=n;i++) {
        scanf("%s",mp1[i]+1);
        for(j=1;j<=m;j++) {
            int x=mp1[i][j]-'0';
            if(x) {
                add(id[i][j],id[i][j]+n*m,x);
            }
        }
    }
    int ans=0;
    for(i=1;i<=n;i++) {
        scanf("%s",mp2[i]+1);
        for(j=1;j<=m;j++) {
            if(mp2[i][j]=='L') {
                add(S,id[i][j],1);
                ans++;
            }
        }
    }
    for(i=1;i<=n;i++) {
        for(j=1;j<=m;j++) {
            if(min(i,min(n+1-i,min(j,m+1-j)))<=d) {
                add(id[i][j]+n*m,T,inf);
            }
            for(k=1;k<=n;k++) {
                for(l=1;l<=m;l++) {
                    if(abs(i-k)+abs(j-l)<=d) {
                        add(id[i][j]+n*m,id[k][l],inf);
                    }
                }
            }
        }
    }
    int f;
    while(bfs()) while((f=dfs(S,inf))>0) ans-=f;
    printf("%d\n",ans);
}

posted @ 2018-12-09 20:32  fcwww  阅读(128)  评论(0编辑  收藏  举报