• 【bzoj1412】[ZJOI2009]狼和羊的故事 网络流最小割


    题目描述

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

    输入

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

    输出

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

    样例输入

    2 2
    2 2
    1 1

    样例输出

    2


    题解

    比较裸的最小割问题

    狼点向周围的空地点和羊点连边,空地向周围的空地和羊点连边。S到狼点、羊点到T连容量为inf的边。

    然后跑最小割。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define N 10010
    #define inf 0x3fffffff
    using namespace std;
    queue<int> q;
    int map[110][110] , num[110][110] , head[N] , to[N << 3] , val[N << 3] , next[N << 3] , cnt = 1 , s , t , dis[N];
    void add(int x , int y , int z)
    {
        to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
        to[++cnt] = x , val[cnt] = 0 , next[cnt] = head[y] , head[y] = cnt;
    }
    bool bfs()
    {
        int x , i;
        while(!q.empty()) q.pop();
        memset(dis , 0 , sizeof(dis));
        dis[s] = 1 , q.push(s);
        while(!q.empty())
        {
            x = q.front() , q.pop();
            for(i = head[x] ; i ; i = next[i])
            {
                if(val[i] && !dis[to[i]])
                {
                    dis[to[i]] = dis[x] + 1;
                    if(to[i] == t) return 1;
                    q.push(to[i]);
                }
            }
        }
        return 0;
    }
    int dinic(int x , int low)
    {
        if(x == t) return low;
        int temp = low , i , k;
        for(i = head[x] ; i ; i = next[i])
        {
            if(val[i] && dis[to[i]] == dis[x] + 1)
            {
                k = dinic(to[i] , min(temp , val[i]));
                if(!k) dis[to[i]] = 0;
                val[i] -= k , val[i ^ 1] += k;
                if(!(temp -= k)) break;
            }
        }
        return low - temp;
    }
    int main()
    {
        int n , m , i , j , ans = 0;
        scanf("%d%d" , &n , &m);
        s = 0 , t = n * m + 1;
        memset(map , 0x3f , sizeof(map));
        for(i = 1 ; i <= n ; i ++ )
            for(j = 1 ; j <= m ; j ++ )
                scanf("%d" , &map[i][j]) , num[i][j] = (i - 1) * m + j;
        for(i = 1 ; i <= n ; i ++ )
        {
            for(j = 1 ; j <= m ; j ++ )
            {
                if(map[i][j] == 2) add(s , num[i][j] , inf);
                if(map[i][j] == 1) add(num[i][j] , t , inf);
                else
                {
                    if(map[i - 1][j] < 2) add(num[i][j] , num[i - 1][j] , 1);
                    if(map[i][j - 1] < 2) add(num[i][j] , num[i][j - 1] , 1);
                    if(map[i][j + 1] < 2) add(num[i][j] , num[i][j + 1] , 1);
                    if(map[i + 1][j] < 2) add(num[i][j] , num[i + 1][j] , 1);
                }
            }
        }
        while(bfs()) ans += dinic(s , inf);
        printf("%d
    " , ans);
        return 0;
    }

     

  • 相关阅读:
    linux使用jstack来找出死循环的java代码
    Dubbo的几种序列化协议
    上传新项目到GitLab
    PI Network项目,手把手教快速挖Pi币
    Oracle数据导出、导入
    如何实现表单标题两端对齐
    cookie 操作记录& vuex 中页面刷新 state 数据丢失的问题
    FCSAN存储与服务器关联映射后在服务器端如何识别操作
    修改密码报-bash: !@#***": event not found
    springboot整合logstash
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6756278.html
Copyright © 2020-2023  润新知