zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    几种简单排序算法
    【转】虚拟机下CentOS7开启SSH连接
    【转】SignalR来做实时Web聊天
    加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用
    C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)
    【C#公共帮助类】给大家分享一些加密算法 (DES、HashCode、RSA、AES等)
    对称加密与非对称加密
    PowerDesigner概念模型与物理模型相互转换及导出数据字典
    SQO2008配置管理工具服务显示远程过程调用失败
    MongoDB学习笔记-数据格式及数据类型
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12507225.html
Copyright © 2011-2022 走看看