• BZOJ 2132 圈地计划 最小割


     首先黑白染色 因为相邻的节点颜色必不同 相同颜色的节点之间没有关系(没有边)

    然后Add(S,黑色点,A[i][j]) (黑色点,T,B[i][j])(S,白色点,B[i][j])(白色点,T,A[i][j])因为黑色点和白色点同属一个S/T才有额外贡献 所以这里A[i][j],B[i][j]要交换连

    sum初始为矩阵里每个点的A,B之和 对于每个点 向它四周相邻的点连(u,v,C[i][j]+C[i'][j']) 注意这里黑色到白色 白色到黑色都要连 因为有属于S/T两种情况

    然后一个点有X个相邻点则sum+=X*C[i][j] 因为上面连的C[i][j]+C[i'][j']容量的边其实有两条但是却不存在同时切两条的情况 最多只会切一条

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef int JQK;
    int n, m;int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}};
    int bl[105][105];
    int sum = 0;
    int A[105][105], B[105][105], C[105][105];
    int main() {
            int n, m;
            scanf("%d %d", &n, &m);
            dinic::MAXP = n * m + 5;
            int s, t;
            s = n * m + 1, t = s + 1;
            dinic::init(s, t);
            for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= m; j++) {
                            scanf("%d", &A[i][j]);
                            sum += A[i][j];
                    }
            for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= m; j++) {
                            scanf("%d", &B[i][j]);
                            sum += B[i][j];
                    }
            for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= m; j++) {
                            scanf("%d", &C[i][j]);
                    }
            for (int i = 1; i <= n; i++) {
                    for (int j = 1; j <= m; j++) {
                            bl[i][j] = (i + j) % 2;
                            int now = (i - 1) * m + j;
                            if (bl[i][j]) {
                                    dinic::addedge(s, now, A[i][j]), dinic::addedge(now, t, B[i][j]);
                            } else {
                                    dinic::addedge(s, now, B[i][j]), dinic::addedge(now, t, A[i][j]);
                            }
                            for (int k = 0; k < 4; k++) {
                                    int dx = i + dir[k][0];
                                    int dy = j + dir[k][1];
                                    if (dx >= 1 && dx <= n && dy >= 1 && dy <= m) {
                                            int aim = (dx - 1) * m + dy;
                                            sum += C[i][j];
                                            dinic::addedge(now, aim, C[i][j] + C[dx][dy]);
                                    }
                            }
                    }
            }
            printf("%d
    ", sum - dinic::Dinic());
            return 0;
    }
  • 相关阅读:
    主流浏览器标签默认样式一览
    为什么要清除默认样式?
    php 的空间命名以及对对象的相关操作,扩展到对数据库的相关函数
    js string
    js基础
    ubuntu-desktop
    php 时期相关函数
    字符串,验证码
    function 相关
    ubuntu_soft相关安装
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11767297.html
Copyright © 2020-2023  润新知