BZOJ1066 [SCOI2007] 蜥蜴(Dinic算法求最大流)

Description

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

Input

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

Output

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

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int inf=1e9;
int r,c,d;
//链式前向星存图 
int head[maxn];
int tol=0;
struct node {
    int u;
    int v;
    int w;
    int next;
}edge[maxn];
void addedge (int u,int v,int w) {
    edge[tol].u=u;
    edge[tol].v=v;
    edge[tol].w=w;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].u=v;
    edge[tol].v=u;
    edge[tol].w=0;
    edge[tol].next=head[v];
    head[v]=tol++;
} 

//Dinic算法求最大流
int dep[maxn];
int inque[maxn];
int vi;
int cur[maxn];
int maxflow=0;
int s,t;
bool bfs () {
    for (int i=0;i<=t;i++) 
        cur[i]=head[i],dep[i]=inf,inque[i]=0;
    dep[s]=0;
    queue<int> q;
    q.push(s);
    while (!q.empty()) {
        int u=q.front();
        q.pop();
        inque[u]=0;
        for (int i=head[u];i!=-1;i=edge[i].next) {
            int v=edge[i].v;
            if (dep[v]>dep[u]+1&&edge[i].w) {
                dep[v]=dep[u]+1;
                if (inque[v]==0) {
                    q.push(v);
                    inque[v]=1;
                }
            }
        }
    } 
    if (dep[t]!=inf) return 1;
    return 0;
}

int dfs (int u,int flow) {
    int increase=0;
    if (u==t) {
        vi=1;
        maxflow+=flow;
        return flow;
    }
    int used=0;
    for (int i=cur[u];i!=-1;i=edge[i].next) {
        cur[u]=i;
        int v=edge[i].v;
        if (edge[i].w&&dep[v]==dep[u]+1) {
            if (increase=dfs(v,min(flow-used,edge[i].w))) {
                used+=increase;
                edge[i].w-=increase;
                edge[i^1].w+=increase;
                if (used==flow) break;
            }
        }
    }
    return used;
}
int Dinic () {
    while (bfs()) {
        vi=1;
        while (vi==1) {
            vi=0;
            dfs(s,inf);
        }
    }
    return maxflow;
} 




int g[1050][1050];
int pos (int x,int y,int f) {
    return (x-1)*c+y+r*c*f;
}
double getDis (int x1,int y1,int x2,int y2) {
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int judge (int x,int y) {
    return x<=d||r-x<d||y<=d||c-y<d;
}
int main(){
    scanf("%d%d%d",&r,&c,&d);
    memset(head,-1,sizeof(head));
    s=0;t=2*r*c+1;
    char s1[maxn];
    for (int i=1;i<=r;i++){
        scanf("%s",s1+1);
        for(int j=1;j<=c;j++) g[i][j]=s1[j]-'0';
    }
    int num=0;
    for(int i=1;i<=r;i++){
        scanf("%s",s1+1);
        for(int j=1;j<=c;j++){
            if(s1[j]=='L') num++,addedge(s,pos(i,j,0),1);
        }
    }
    for(int i=1;i<=r;i++){
        for(int j=1;j<=c;j++){
            if(g[i][j]){
                addedge(pos(i,j,0),pos(i,j,1),g[i][j]);
            }
        }
    }
    for(int x1=1;x1<=r;x1++){
        for(int y1=1;y1<=c;y1++){
            if(!g[x1][y1]) continue;
            for(int x2=1;x2<=r;x2++){
                for(int y2=1;y2<=c;y2++){
                    if (x1==x2&&y1==y2) continue;
                    if (g[x2][y2]&&getDis(x1,y1,x2,y2)<=d){
                        addedge(pos(x1,y1,1),pos(x2,y2,0),inf);
                        addedge(pos(x2,y2,1),pos(x1,y1,0),inf);
                    }
                }
            }
        }
    }
    for(int i=1;i<=r;i++){
        for(int j=1;j<=c;j++){
            if(judge(i,j)){
                addedge(pos(i,j,1),t,inf);
            }
        }
    }
    printf("%d",num-Dinic()); 
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zhanglichen/p/12507225.html