JOJ 2656: 霍格瓦兹魔法阵 //最小割

2656: 霍格瓦兹魔法阵

Result TIME Limit MEMORY Limit Run Times AC Times JUDGE
2s 32768K 89 13 Standard

最近,伏地魔开始网罗党羽, 许多女巫和男巫为了获得他赋予的力量加入了他的阵营。为了抵抗伏地魔的进攻,霍格瓦兹的魔法师们摆出了一个 n * m 方格的魔法方阵,每个方格中都站有一位魔法师。当然,魔法师们都有自己的魔法值,用非负整数表示。 然而,对伏地魔发起攻击时,为了安全起见,任意两个相邻的魔法师 (上下相邻或左右相邻) 不能同时施展魔法。为了打败强大的伏地魔,你能帮助霍格瓦兹的魔法师们找出最大可能的攻击魔法值么?

Input

输入含有多组case 每个case的第一行有两个整数 n 和 m ,代表魔法方阵的规模接下来输入的是 n * m 的非负整数矩阵。 n和m均不超过50 当n=m=0时,输入结束

Output

对每个case, 输出最大可能魔法值

Input

3 2
1 2
3 4
5 6

3 3
75 15 21 
75 15 28 
34 70 5

0 0

Output

11
188

 

Problem Source: ccst

 

This problem is used for contest: 162 

Submit / Problem List / Status / Discuss

 

#include<cstdio>
#include<cstring>
const  int MAXN=2510;
const  int MAXM=20000;
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)
    {
        if(n==0&&m==0)  break;
        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;
}

你可能感兴趣的:(list,System,input,output)