hdu2686--Matrix(拆点+最大费用)

Matrix

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1665    Accepted Submission(s): 901

Problem Description

Yifenfei very like play a number game in the n*n Matrix. A positive integer number is put in each area of the Matrix.

Every time yifenfei should to do is that choose a detour which frome the top left point to the bottom right point and than back to the top left point with the maximal values of sum integers that area of Matrix yifenfei choose. But from the top to the bottom
can only choose right and down, from the bottom to the top can only choose left and up. And yifenfei can not pass the same area of the Matrix except the start and end.

Input

The input contains multiple test cases.

Each case first line given the integer n (2<n<30)

Than n lines,each line include n positive integers.(<100)

Output

For each test case output the maximal values yifenfei can get.

Sample Input

2
10 3
5 10
3
10 3 3
2 5 3
6 7 10
5
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9

Sample Output

28
46
80

从左上到右下在走回左上,每个点只能经过一次,问最大的权值和是多少

可以当做成从左上到右下走过两次,至于每个点只能走过一次,需要拆点,每个点i到对应的i点容量是1,使得该点只能走过一次。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define maxn 3000
#define INF 0x3f3f3f3f
struct node
{
    int v , w , s ;
    int next ;
} p[3000000];
int a[50][50] , head[maxn] , cnt ;
int pre[maxn] , vis[maxn] , dis[maxn] ;
queue <int> q ;
void add(int u,int v,int w,int s)
{
    p[cnt].v = v ; p[cnt].w = w ; p[cnt].s = s ;
    p[cnt].next = head[u] ; head[u] = cnt++ ;
    p[cnt].v = u ; p[cnt].w = 0 ; p[cnt].s = -s ;
    p[cnt].next = head[v] ; head[v] = cnt++ ;
}
int spfa(int s,int t)
{
    int u , v , i ;
    memset(dis,INF,sizeof(dis));
    dis[s] = 0 ; vis[s] = 1 ;
    pre[s] = pre[t] = -1 ;
    while( !q.empty() )
        q.pop();
    q.push(s) ;
    while( !q.empty() )
    {
        u = q.front();
        q.pop();
        vis[u] = 0 ;
        for(i = head[u] ; i != -1 ; i = p[i].next)
        {
            v = p[i].v ;
            if( p[i].w && dis[v] > dis[u] + p[i].s )
            {
                dis[v] = dis[u] + p[i].s ;
                pre[v] = i ;
                if( !vis[v] )
                {
                    vis[v] = 1 ;
                    q.push(v) ;
                }
            }
        }
    }
    if( pre[t] == -1 )
        return 0 ;
    return 1 ;
}
void f(int s,int t)
{
    memset(pre,-1,sizeof(pre));
    memset(vis,0,sizeof(vis));
    int i , ans = 0 , min1 ;
    while( spfa(s,t) )
    {
        min1 = INF ;
        for(i = pre[t] ; i != -1 ; i = pre[ p[i^1].v ])
            if( p[i].w < min1 )
                min1 = p[i].w ;
        for(i = pre[t] ; i != -1 ; i = pre[ p[i^1].v ])
        {
            p[i].w -= min1 ;
            p[i^1].w += min1 ;
            ans += p[i].s ;
        }
    }
    printf("%d\n", -ans);
}
int main()
{
    int i , j , n , b , temp;
    while(scanf("%d", &n)!=EOF)
    {/*和D相同,不过这一个题换成了每个点只能经过一次,要求从左上走到右下,再走回左上,可以认为是从左上走到右下两次 */
        memset(head,-1,sizeof(head));
        cnt = 0 ; temp = n*n ;
        for(i = 1 ; i <= n ; i++)
            for(j = 1 ; j <= n ; j++)
            {
                scanf("%d", &a[i][j]);
                b = (i-1)*n + j ;
                if(b == 1 || b == temp)
                    add(b,b+temp,1,0);//源点和汇点会被走两次
                add(b,b+temp,1,-a[i][j]);//拆点操作,使得每个点只会被经过一次。
            }
        for(i = 1 ; i <= n ; i++)
            for(j = 1 ; j <= n ; j++)
            {
                b = (i-1)*n+j ;
                if(i > 1)
                    add(b-n+temp,b,1,0);
                if(j > 1)
                    add(b-1+temp,b,1,0);
            }
        add(0,1,2,0);
        add(2*n*n,2*n*n+1,2,0);
        f(0,2*n*n+1);
    }
    return 0;
}

hdu2686--Matrix(拆点+最大费用),布布扣,bubuko.com

时间: 2024-10-11 06:46:49

hdu2686--Matrix(拆点+最大费用)的相关文章

POJ 3422 Kaka&#39;s Matrix Travels(最大费用最大流 + 拆点)

题目链接:http://poj.org/problem?id=3422 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking

POJ--3422--Kaka&#39;s Matrix Travels【最小费用最大流+拆点】

链接:http://poj.org/problem?id=3422 卡卡 题意:卡卡的矩阵之旅,有一个n*n的矩阵,卡卡要从左上角走到右下角,每次他只能往右或往下走,卡卡可以走k遍这个矩阵,每个点有一个num值,卡卡走到这里可以获得num点,一个点只能获得一次num值,问卡卡走完k遍后身上num值最大可以是多少? 思路:其实看到这题时没思路,图论书上说了建图的方式,但没有说为什么,我不解,网上搜了一下解题报告,百度了两页,我看到的博客都是写了如何建图,但没有写为什么要这么建..我觉得我真是弱渣,

poj 3422 Kaka&#39;s Matrix Travels 【最大费用最大流】【好题】

Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8729   Accepted: 3498 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka mo

POJ3422 Kaka&amp;#39;s Matrix Travels 【最大费用最大流】

Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8006   Accepted: 3204 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka mo

POJ3422 Kaka&#39;s Matrix Travels 【最大费用最大流】

Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8006   Accepted: 3204 Description On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka mo

POJ 3422 Kaka&#39;s Matrix Travels(网络流之费用流)

题目地址:POJ 3422 方法是对每个点i拆点成i'和i'',然后对每个i'和i''连一条费用为该点值,流量为1的边,再连1条费用为0,流量为k-1的边. 然后对每个点与右边下边相邻的点连边,流量均为INF,费用均为0.需要再建一源点与汇点,对于k次只需要在源点与汇点处进行限制即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #inclu

ACdream-1171 Matrix sum, 最大费用最大流

Matrix sum Time Limit: 8000/4000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description sweet和zero在玩矩阵游戏,sweet画了一个N * M的矩阵,矩阵的每个格子有一个整数.zero给出N个数Ki,和M个数Kj,zero要求sweet选出一些数,满足从第 i 行至少选出了Ki个数,第j列至少选出了K

Acdream 1171 Matrix sum 上下界费用流

题目链接:点击打开链接 Matrix sum Time Limit: 8000/4000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description sweet和zero在玩矩阵游戏,sweet画了一个N * M的矩阵,矩阵的每个格子有一个整数.zero给出N个数Ki,和M个数Kj,zero要求sweet选出一些数,满足从第 i 行至少选出了Ki

POJ 3422 Kaka&#39;s Matrix Travels 【最小费用最大流】

题意: 卡卡有一个矩阵,从左上角走到右下角,卡卡每次只能向右或者向下.矩阵里边都是不超过1000的正整数,卡卡走过的元素会变成0,问卡卡可以走k次,问卡卡最多能积累多少和. 思路: 最小费用最大流的题目. 建图自己没想出来,看了大神的建边,把每个点分解成两个点,一个代表进入一个代表出去,然后每个进入和每个出去连边,容量是1价值是这个点的矩阵的数值.然后因为可以不进去,所以起点要和别的矩阵元素的起点建边,终点也要和别的矩阵矩阵元素的起点建边,最后跑下最小费用最大流. 这题最右下角的矩阵元素需要特殊