zoukankan      html  css  js  c++  java
  • BZOJ1412 [ZJOI2009] 狼和羊的故事(Dinic算法求最大流)

    Description

    “狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

    Input

    文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

    Output

    文件中仅包含一个整数ans,代表篱笆的最短长度。

     

    题解:

    新增一个0号点作为源点,新增一个10001号点作为汇点,源点向所有狼连一条容量为无限大的边,所有狼向汇点连一条容量为无限大的边。然后如果这个点不是狼的同时它四周的点也不是狼,就在这个点与它四周的点之间连一条容量为1的边,然后对全图跑一遍Dinic算法求最小割。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int inf=1e9;
    int X[4]={1,0,-1,0};
    int Y[4]={0,1,0,-1};
    int g[105][105];
    int N,M;
    //链式前向星建图部分 
    struct node {
        int u;
        int v;
        int w;
        int next;
    }edge[maxn];
    int head[maxn];
    int tol=0;
    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++;
    } 
    
    
    //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 main () {
        scanf("%d%d",&N,&M);
        memset(head,-1,sizeof(head));
        s=0;t=10001;
        for (int i=1;i<=N;i++)
            for (int j=1;j<=M;j++)
                scanf("%d",&g[i][j]);
        for (int i=1;i<=N;i++) 
            for (int j=1;j<=M;j++) {
                if (g[i][j]==1) {
                    addedge(0,(i-1)*M+j,inf);
                    addedge((i-1)*M+j,0,0);
                }
                else if (g[i][j]==2) {
                    addedge((i-1)*M+j,t,inf);
                    addedge(t,(i-1)*M+j,0);
                }
                for (int k=0;k<4;k++) {
                    int tx=i+X[k];
                    int ty=j+Y[k];
                    if (tx<1||tx>N||ty<1||ty>M||g[i][j]==2) continue;
                    if (g[i][j]!=1||g[tx][ty]!=1) {
                        addedge((i-1)*M+j,(tx-1)*M+ty,1);
                        addedge((tx-1)*M+ty,(i-1)*M+j,0); 
                    }
                }
            }
        printf("%d
    ",Dinic());
        return 0;
    }
  • 相关阅读:
    挑战程序设计竞赛 dp
    算法导论 动态规划
    算法导论第二章
    divide conquer
    时间戳
    bootstrap 针对超小屏幕和中等屏幕设备定义的不同的类
    jQuery中的Ajax
    怎么判断一个变量是Null还是undefined
    认识Ajax
    关于apache
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12502726.html
Copyright © 2011-2022 走看看