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