码迷,mamicode.com
首页 > 其他好文 > 详细

网络流 [HDU 1565] 方格取数(1)

时间:2015-01-08 00:56:37      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

方格取数(1)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5961    Accepted Submission(s): 2268


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
 
最大点权独立集
弱弱的EK算法
/* ***********************************************
Author        :哈特13
Created Time  :2015/1/7 23:38:02
File Name     :HDU 1565 方格取数(1).cpp
************************************************ */

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define N 510

int n;
int src;
int des;
int sum;
int pre[N];
int mpt[N][N];
int map[N][N];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
queue<int> q;

bool bfs()
{
    while(!q.empty()) q.pop();
    memset(pre,-1,sizeof(pre));
    pre[src]=0;
    q.push(src);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int v=0;v<=n*n+1;v++)
        {
            if(pre[v]==-1 && mpt[u][v]>0)
            {
                pre[v]=u;
                if(v==des) return 1;
                q.push(v);
            }
        }
    }
    return 0;
}
int EK()
{
    int maxflow=0;
    while(bfs())
    {
        int minflow=INF;
        for(int i=des;i!=src;i=pre[i])
            minflow=min(minflow,mpt[pre[i]][i]);
        maxflow+=minflow;
        for(int i=des;i!=src;i=pre[i])
        {
            mpt[pre[i]][i]-=minflow;
            mpt[i][pre[i]]+=minflow;
        }
    }
    return maxflow;
}
int main()
{
    int i,j,k;
    while(scanf("%d",&n)!=EOF)
    {
        sum=0;
        memset(mpt,0,sizeof(mpt));
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&map[i][j]);
                sum+=map[i][j];
            }
        }
        src=0;
        des=n*n+1;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if((i+j)%2==0) mpt[src][(i-1)*n+j]=map[i][j];
                else mpt[(i-1)*n+j][des]=map[i][j];
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if((i+j)%2==0)
                {
                    for(k=0;k<4;k++)
                    {
                        int x=i+dir[k][0];
                        int y=j+dir[k][1];
                        if(x>=1 && x<=n && y>=1 && y<=n)
                        {
                            mpt[(i-1)*n+j][(x-1)*n+y]=INF;
                        }
                    }
                }
            }
        }
        printf("%d\n",sum-EK());
    }
    return 0;
}

 

网络流 [HDU 1565] 方格取数(1)

标签:

原文地址:http://www.cnblogs.com/hate13/p/4209760.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!