1. 程式人生 > >hdu 1565 方格取數(1)(最小割)

hdu 1565 方格取數(1)(最小割)

方格取數(1)

Problem Description 給你一個n*n的格子的棋盤,每個格子裡面有一個非負數。
從中取出若干個數,使得任意的兩個數所在的格子沒有公共邊,就是說所取的數所在的2個格子不能相鄰,並且取出的數的和最大。
Input 包括多個測試例項,每個測試例項包括一個整數n 和n*n個非負數(n<=20)
Output 對於每個測試例項,輸出可能取得的最大的和
Sample Input 3 75 15 21 75 15 28 34 70 5
Sample Output 188
Author ailyanlu
Source Happy 2007 設定源點與匯點s,t 源點與白點連邊,容量為白點上的數 黑點與匯點連邊,容量為黑點上的數 白點與他周圍的黑點連邊,容量為inf 這樣我們只要求這個圖的最小割,使得源點與匯點不想連,然後剩下的數字即為所求 定理 最小割=最大流
#include <iostream>
#include <cstdio>
#include <cstring>
#include<queue>
#define maxn 555
#define inf 9999999
using namespace std;

int map[maxn][maxn],tag[maxn],pre[maxn],f[maxn];
int a[maxn][maxn];
int n,s,t,ans,tot,N=99;
int q[maxn],bot,top;

void init()
{
  s=0,t=n*n+1,ans=tot=0;
  memset(map,0,sizeof(map));
}

void graph()
{
  for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
      if((i+j)%2==1)
      {
        int cur=i*n+j-n;
        map[s][cur]+=a[i][j];
        if (i>1) map[cur][cur-n]=inf;
        if (i<n) map[cur][cur+n]=inf;
        if (j>1) map[cur][cur-1]=inf;
        if (j<n) map[cur][cur+1]=inf;
      }
      else map[i*n+j-n][t]+=a[i][j];
}
void bfs()
{
    int u,v;
    queue<int>q;
    while(1)
    {
        memset(f,0,sizeof(f));
        f[s]=inf;
        while(!q.empty())
            q.pop();
        q.push(s);
        while(!q.empty())
        {
            u=q.front();
            q.pop();
            for(v=s;v<=t;v++)
            {
                if(!f[v]&&map[u][v]>0)
                {
                    pre[v]=u;
                    q.push(v);
                    f[v]=min(f[u],map[u][v]);
                }
            }
            if(f[t])
                break;
        }
        if(f[t]==0)
            break;
        ans+=f[t];
        for(int i=t;i!=s;i=pre[i])
        {
            map[pre[i]][i]-=f[t];
            map[i][pre[i]]+=f[t];
        }
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        init();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&a[i][j]),tot+=a[i][j];
        graph();
        bfs();
        printf("%d\n",tot-ans);
    }
    return 0;
}