bzoj1066 蜥蜴

Description

在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。

Input

输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

Output

输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

最大流

每条石柱拆成两个点,连边容量为石柱高度

在距离不超过d的石柱间连边,容量为inf

从源点连边到每条有蜥蜴的石柱,容量为1

从可以跳到图外的点连边到汇点,容量为inf

#include<cstdio>
#include<cstring>
struct edge{
    int nx,w;
    edge(){}
    edge(int a,int b){
        nx=a;
        w=b;
    }
}es[100005];
int ep=2;
const int S=0,T=1,INF=2147483647;
int g[100005][2],gp=1005;
int h[10005];
int v[105][105];
int q[10005];
int n,m,ans=0,mx,ls=0;
int ids[24][24],idp=2;
int hs[24][24];
char c;
inline int min(int a,int b){return a<b?a:b;}
inline void addedge(int s,int t,int w){
    es[ep]=edge(t,w);
    g[gp][0]=ep++;
    g[gp][1]=g[s][1];
    g[s][1]=gp++;
    es[ep]=edge(s,0);
    g[gp][0]=ep++;
    g[gp][1]=g[t][1];
    g[t][1]=gp++;
}
inline bool bfs(){
    int qs=0,qe=0;
    q[qe++]=S;
    memset(h,-1,sizeof h);
    h[S]=0;
    while(qs<qe){
        int w=q[qs++];
        int i=w;
        while(i=g[i][1]){
            int e=g[i][0];
            int u=es[e].nx;
            if(h[u]!=-1||!es[e].w)continue;
            h[u]=h[w]+1;
            q[qe++]=u;
        }
    }
    return h[T]!=-1;
}
int dfs(int w,int f){
    if(w==T)return f;
    int i=w;
    int used=0,c;
    while(i=g[i][1]){
        int e=g[i][0];
        int u=es[e].nx;
        if(h[u]!=h[w]+1||es[e].w==0)continue;
        c=f-used;
        c=dfs(u,min(c,es[e].w));
        es[e].w-=c;
        es[e^1].w+=c;
        used+=c;
        if(used==f)return f;
    }
    if(!used)h[w]=-1;
    return used;
}
char gc(){
    char c=getchar();
    while((c<'0'||c>'9')&&c!='L'&&c!='.')c=getchar();
    return c;
}
int main(){
    scanf("%d%d%d",&n,&m,&mx);
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            ids[i][j]=idp++;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            c=gc();
            hs[i][j]=c-'0';
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(hs[i][j]>0){
                addedge(ids[i][j],ids[i][j]+n*m,hs[i][j]);
                bool o=0;
                for(int x=-mx;x<=mx;x++){
                    for(int y=-mx;y<=mx;y++){
                        if(x*x+y*y>mx*mx)continue;
                        if(i+x<0||i+x>=n||j+y<0||j+y>=m){
                            o=1;
                            continue;
                        }
                        if(hs[i+x][j+y]==0)continue;
                        addedge(ids[i][j]+n*m,ids[i+x][j+y],INF);
                    }
                }
                if(o)addedge(ids[i][j]+n*m,T,INF);
            }
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            c=gc();
            if(c=='L')addedge(S,ids[i][j],1),ls++;
        }
    }
    while(bfs())ans+=dfs(S,INF);
    printf("%d",ls-ans);
    return 0;
}

 

你可能感兴趣的:(bzoj1066 蜥蜴)