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;
    }
  • 相关阅读:
    如何在iTerm2中配置oh my zsh?
    sublime中格式化jsx文件
    ES6 new syntax of Literal
    ES6 new syntax of Rest and Spread Operators
    How to preview html file in our browser at sublime text?
    ES6 new syntax of Default Function Parameters
    ES6 new syntax of Arrow Function
    七牛云2018春招笔试题
    Spring-使用注解开发(十二)
    Spring-声明式事物(十一)
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12507225.html
Copyright © 2011-2022 走看看