[BZOJ 1475]方格取数

来源:互联网 发布:甘肃广电网络最新人事 编辑:程序博客网 时间:2024/05/22 15:39
1475: 方格取数
Description
在一个n*n的方格里,每个格子里都有一个正整数。从中取出若干数,使得任意两个取出的数所在格子没有公共边,且取出的数的总和尽量大。
Input
第一行一个数n;(n<=30) 接下来n行每行n个数描述一个方阵
Output
仅一个数,即最大和
Sample Input
2
1 2
3 5

Sample Output

6


最小割


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define maxn 1000010using namespace std;int n, m;const int inf = 0x7fffffff;struct Edge{int to, next, w;}edge[maxn];int h[10001], cnt = 1;void add(int u, int v, int w){cnt ++;edge[cnt].to = v;edge[cnt].next = h[u];edge[cnt].w = w;h[u] = cnt;swap(u, v), w = 0;cnt ++;edge[cnt].to = v;edge[cnt].next = h[u];edge[cnt].w = w;h[u] = cnt;}queue<int>Q;int d[10001], S, T;bool BFS(){memset(d, -1, sizeof d);Q.push(S);d[S] = 0;while(!Q.empty()){int u = Q.front();Q.pop();for(int i = h[u]; i; i = edge[i].next){if(!edge[i].w)continue;int v = edge[i].to;if(d[v] == -1){d[v] = d[u] + 1;Q.push(v);}}}return d[T] != -1;}int DFS(int x, int a){if(x == T || a == 0)return a;int used = 0, f;for(int i = h[x]; i; i = edge[i].next){int v = edge[i].to;if(d[v] == d[x] + 1){f = DFS(v, min(a - used, edge[i].w));edge[i].w -= f;edge[i ^ 1].w += f;used += f;if(used == a)return used;}}if(used == 0)d[x] = -1;return used;}int Dinic(){int ans = 0;while(BFS())    ans += DFS(S, inf);return ans;}int a[50][50], id[50][50];const int dx[] = {0, 0, 1, -1};const int dy[] = {1, -1, 0, 0};int main(){scanf("%d", &n);S = 0, T = n * n + 1;int total = 0;for(int i = 1; i <= n; i ++)for(int j = 1; j <= n; j ++){            scanf("%d", &a[i][j]);            total += a[i][j];}        int cnt = 0;for(int i = 1; i <= n; i ++)for(int j = 1; j <= n; j ++)    id[i][j] = ++ cnt;    for(int i = 1; i <= n; i ++)for(int j = 1; j <= n; j ++){            if(i + j & 1)add(S, id[i][j], a[i][j]);            else add(id[i][j], T, a[i][j]);            for(int k = 0; k < 4; k ++){int u = i + dx[k], v = j + dy[k];if(u == 0 || v == 0 || u > n || v > n)    continue;if(i + j & 1)add(id[i][j], id[u][v], inf);else add(id[u][v], id[i][j], inf);            }}    printf("%d\n", total - Dinic());return 0;}


0 0