zoukankan      html  css  js  c++  java
  • 【网络流】【BZOJ1006】【SCOI2007】蜥蜴

    学弟@lher在周末训练赛中出的题目的原题(这个人拿省选题来当作提高组模拟,太丧了。。。)

    题意简析:看题目:)

    解题思路:题目显然是最大流。

    首先拆点将点权变为边权,然后按照题意对于所有有跳板的点向可以跳到的点连一条权值为inf的边,对于能够跳出地图边界的点,将它与汇点连一条权值为inf的边。对于有蜥蜴的点,从源点向这个点连一条权值为1的边,然后跑一次最大流,答案就是蜥蜴数-最大流。

    AC代码:

    #include<stdio.h>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #define ll long long
    #define inf 0x7fffffff
    using namespace std;
    struct zxy{
        int next,to,v;
    }edge[1000005];
    int n,m,d,head[10005],iter[10005],lev[10005],que[100005],cnt=1,mz=0;
    bool b[55][55];
    inline int getno(int x,int y){ return (x-1)*m+y;}
    inline int getdis(int x,int y,int a,int b){ return ceil(sqrt((x-a)*(x-a)+(y-b)*(y-b)));}
    inline void ins(int x,int y,int l){edge[++cnt].next=head[x],head[x]=cnt,edge[cnt].to=y,edge[cnt].v=l;}
    inline int in(){
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    inline bool bfs(int s,int e){
        memset(lev,-1,sizeof(lev));
        int t=1,h=0;
        que[1]=s;
        lev[s]=0;
        do{
            h++;
            int k=head[que[h]];
            while(k){
                if (lev[edge[k].to]==-1&&edge[k].v){
                    lev[edge[k].to]=lev[que[h]]+1;
                    que[++t]=edge[k].to;
                }
                k=edge[k].next;
            }
        }while(h<t);
        return lev[e]!=-1;
    }
    inline int dfs(int u,int v,int f){
        if (u==v) return f;
        int used=0,k=head[u];
        while(k){
            if (edge[k].v&&lev[edge[k].to]==lev[u]+1){
                int w=dfs(edge[k].to,v,min(edge[k].v,f-used));
                used+=w;
                edge[k].v-=w;
                edge[k^1].v+=w;
                if (used==f) return used;
            }
            k=edge[k].next;
        }
        return used;
    }
    int dinic(int s,int t){
        int flow=0;
        while(bfs(s,t))
            flow+=dfs(s,t,inf);
        return flow;
    }
    void init(){
        n=in(),m=in(),d=in();
        for (int i=1; i<=n; ++i){
            for (int j=1; j<=m; ++j){
                int x=getchar()-'0',no=getno(i,j);
                if (x) ins(no,no+n*m,x),ins(no+n*m,no,0),b[i][j]=1;
            }
            getchar();
        }
        for (register int i=1; i<=n; ++i){
            for(register int j=1; j<=m; ++j)
                if (getchar()=='L') ++mz,ins(0,getno(i,j),1),ins(getno(i,j),0,0);
            getchar();
        }
        for (register int i=1; i<=n; ++i)
            for (register int j=1; j<=m; ++j)
            if(b[i][j]){
                if (i-d<1||i+d>n||j-d<1||j+d>m) ins(getno(i,j)+n*m,n*m*2+1,inf),ins(n*m*2+1,getno(i,j)+n*m,0);
                for (int k=(i-d<1?1:i-d); k<=(i+d>n?n:i+d); ++k)
                    for (int t=(j-d<1?1:j-d); t<=(j+d>m?m:j+d); ++t)
                        if (b[k][t]&&getdis(i,j,k,t)<=d&&(i!=k||j!=t))
                            ins(getno(i,j)+n*m,getno(k,t),inf),ins(getno(k,t),getno(i,j)+n*m,0);
            }
    }
    int main(){
        init();
        printf("%d",mz-dinic(0,2*n*m+1));
        return 0;
    }

     本文由Melacau编写,Melacau代表M星向您问好,如果您不是在我的博客http://www.cnblogs.com/Melacau上看到本文,请您向我联系,email:13960948839@163.com.

  • 相关阅读:
    50 个 jQuery 插件可将你的网站带到另外一个高度
    查看占用IO的进程
    google全球地址
    php http请求封装
    如何促使团队紧密协作
    pureftpd.passwd解析
    goaccess生成nginx每日访问纪录
    bootstrap的一些资源
    php write_ini_file
    mysql查询区分大小写
  • 原文地址:https://www.cnblogs.com/Melacau/p/BZOJ1006.html
Copyright © 2011-2022 走看看