SOJ 3107 Select//最小割

来源:互联网 发布:js获取map对象长度 编辑:程序博客网 时间:2024/05/21 11:29

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



windy7926778

 

 

#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;
}