Description
n*m 个方格,每个方格中有一个不大于 100000 的正整数。
从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大。
Input
输入包含多组测试数据,每组数据第 1 行有 2 个正整数 n m 。
接下来的 n 行,每行有 m 个正整数,表示棋盘方格中的数。
( 1 <= n,m <= 100 )
Output
每组数据输出一行,为最大的总和。
Sample Input
3 3
1 2 3
3 2 3
2 3 1
3 3
1 100 1
1 1 1
1 1 100
Sample Output
11
201
Author
#include<cstdio>
#include<cstring>
const int MAXN=10010;
const int MAXM=100000;
const int INF = 0x7fffffff;
struct Edge
{
int st, ed,next,flow;
} edge[MAXM];
int head[MAXN],value[MAXN];
int N, M, F, E;
int src, dest;
int seq[MAXM], sl;
int ans = 0;
int map[101][101];
void add_edge(int u, int v, int w)
{
edge[E].flow = w;
edge[E].st = u;
edge[E].ed = v;
edge[E].next = head[u];
head[u] = E++;
edge[E].flow = 0;
edge[E].st = v;
edge[E].ed = u;
edge[E].next = head[v];
head[v] = E++;
}
int d[MAXN];
bool dinic_bfs(void)
{
int i, j;
memset(d, -1, sizeof(d));
int que[MAXN], rear = 1;
que[0] = src;
d[src] = 0;
for(i = 0; i < rear; i++)
{
for(j = head[que[i]]; j != -1; j = edge[j].next)
{
if(d[edge[j].ed] == -1 && edge[j].flow > 0)
{
d[edge[j].ed] = d[que[i]]+1;
que[rear++] = edge[j].ed;
if(edge[j].ed==dest) return true;
}
}
}
return false;
}
int dinic_dfs(void)
{
int stk[MAXN], top = 0;
int ret = 0, cur, ptr, pre[MAXN], minf, i;
bool del[MAXN];
memset(del, false, sizeof(del));
stk[top++] = src;
pre[src] = src;
cur = src;
while(top)
{
while(cur != dest && top)
{
for(i = head[cur]; i != -1; i = edge[i].next)
{
if(d[edge[i].ed] == d[cur]+1 && edge[i].flow > 0 && !del[edge[i].ed])
{
stk[top++] = edge[i].ed;
cur = edge[i].ed;
pre[edge[i].ed] = i;
break;
}
}
if(i == -1)
{
del[cur] = 1;
top--;
if(top) cur = stk[top-1];
}
}
if(cur == dest)
{
minf = INF;
while(cur != src)
{
cur = pre[cur];
if(edge[cur].flow < minf)
minf = edge[cur].flow;
cur = edge[cur].st;
}
cur = dest;
while(cur != src)
{
cur = pre[cur];
edge[cur].flow -= minf;
edge[cur^1].flow += minf;
if(edge[cur].flow == 0)
ptr = edge[cur].st;
cur = edge[cur].st;
}
while(top > 0&& stk[top-1] != ptr) top--;
if(top) cur = stk[top-1];
ret += minf;
}
}
return ret;
}
int Dinic()
{
int ret = 0, t;
while(dinic_bfs())
{
t = dinic_dfs();
if(t) ret += t;
else break;
}
return ret;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
src=0;
dest=n*m+1;
E=0;
memset(head,-1,sizeof(head));
int sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
sum+=map[i][j];
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
int t=(i-1)*m+j;
if((i+j)%2==0)
{
add_edge(0,t,map[i][j]);
if(i+1<=n) add_edge(t,t+m,INF);
if(j+1<=m) add_edge(t,t+1,INF);
}
else
{
add_edge(t,n*m+1,map[i][j]);
if(i+1<=n) add_edge(t+m,t,INF);
if(j+1<=m) add_edge(t+1,t,INF);
}
}
printf("%d/n",sum-Dinic());
}
return 0;
}