其他分享
首页 > 其他分享> > P2774 方格取数问题(最小割)

P2774 方格取数问题(最小割)

作者:互联网

传送门

题目描述:

有一个 m 行 n 列的方格图,每个方格中都有一个正整数。现要从方格中取数,使任意两个数所在方格没有公共边,且取出的数的总和最大,请求出最大的和。

思路:把棋盘通过纵横坐标和(i+j)的奇偶性拆成黑色和白色的点,然后选择黑色/白色的点与源点连边,权值为点权,白色/黑色的点与汇点连边,权值为点权,然后再把与

源点连边的点(假设为黑)对其周围的点(白点)连边,权值取inf,然后用所有点的权值和sum-最小割就是最大选择。

AC代码:

int n, m;
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0,0,-1,1 };
bool check(int x, int y) {
    return x >= 1 && x <= m && y >= 1 && y <= n;
}
int main() {
    //freopen("test.txt", "r", stdin);
    scanf("%d%d", &m, &n);
    ll sum = 0;
    s = (m + 1) * n + 1, t = s + 1;
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            int f; scanf("%d", &f);
            sum += f;
            if ((i + j) & 1) {
                add(s, i * n + j, f);
                for (int d = 0; d < 4; d++) {//与源点连边的点和其周围的点连边
                    int x = i + dx[d];
                    int y = j + dy[d];
                    if (check(x, y)) {
                        add(i * n + j, x * n + y, inf);
                    }
                }
            }
            else {
                add(i * n + j, t, f);
            }
        }
    }
    ll mincut = dinic();
    printf("%lld\n", sum - mincut);
    return 0;
}

 

标签:连边,int,源点,取数,方格,&&,权值,P2774
来源: https://www.cnblogs.com/MYMYACMer/p/14658249.html