hdu 3376 Matrix Again【最大费用流】

Matrix Again

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)

Total Submission(s): 2947    Accepted Submission(s): 860

Problem Description

Starvae 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 starvae should to do is that choose a detour which from 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 starvae 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 starvae can not pass the same area of the Matrix except the start and end..

Do you know why call this problem as “Matrix Again”? AS it is like the problem 2686 of HDU.

Input

The input contains multiple test cases.

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

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

Output

For each test case output the maximal values starvae 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

分析:这道题和hdu 2628(Matrix)一模一样,只不过数据变大了,我一开始认为要卡时间或卡内存,可不知怎么优化,于是抱着试试的心态把数组开大结果过了。

那大家可以看一下我的hdu 2628 有讲解。

代码示例:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#define Min(a,b) a<b?a:b
#define inf 0xffffff
#define maxn 4000000+10
#define maxm 1000000+10
using namespace std;
typedef struct
{
    int from,to,next;
    int val,cost;
}node;
node E[maxn];
int head[maxm],dis[maxm],pre[maxm],pos[maxm],visit[maxm],cnt;
void init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
}
void add(int from,int to,int val,int cost)
{
    E[cnt].from=from,E[cnt].to=to,E[cnt].val=val,E[cnt].cost=cost;
    E[cnt].next=head[from],head[from]=cnt++;
    E[cnt].from=to,E[cnt].to=from,E[cnt].val=0,E[cnt].cost=-cost;
    E[cnt].next=head[to],head[to]=cnt++;
}
bool spfa(int s,int t,int n)
{
    int val,cost,to;
    for(int i=0;i<=n;i++)
    {
        dis[i]=inf,visit[i]=0,pre[i]=-1;
    }
    dis[s]=0,visit[s]=1,pre[s]=s;
    queue<int>Q;
    Q.push(s);
    while(!Q.empty())
    {
        int k=Q.front();
        Q.pop();
        visit[k]=0;
        for(int i=head[k];i!=-1;i=E[i].next)
        {
            to=E[i].to,val=E[i].val,cost=E[i].cost;
            if(val>0&&dis[k]+cost<dis[to])
            {
                dis[to]=dis[k]+cost;
                pre[to]=k;
                pos[to]=i;
                if(visit[to])
                continue;
                visit[to]=1;
                Q.push(to);
            }
        }
    }
    if(pre[t]!=-1&&dis[t]<inf)
    return true;
    return false;
}
int MinCostFlow(int s,int t,int n)
{
    int netflow=0,costflow=0,min;
    while(spfa(s,t,n))
    {
        min=inf;
        for(int i=t;i!=s;i=pre[i])
        {
            min=Min(min,E[pos[i]].val);
        }
        netflow+=min;
        costflow+=min*dis[t];
        for(int i=t;i!=s;i=pre[i])
        {
            E[pos[i]].val-=min;
            E[pos[i]^1].val+=min;
        }
    }
    return -costflow;
}
int main()
{
    int n,s,t,x,sum;
    while(~scanf("%d",&n))
    {
        init();
        sum=0;
        for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            scanf("%d",&x);
            if((i==0&&j==0)||(i==n-1&&j==n-1))
            {
                add(i*n+j,i*n+j+n*n,2,-x);
                sum+=x;
            }
            else
            {
                add(i*n+j,i*n+j+n*n,1,-x);
            }
            if(i+1<n)
            {
                add(i*n+j+n*n,(i+1)*n+j,1,0);
            }
            if(j+1<n)
            {
                add(i*n+j+n*n,i*n+j+1,1,0);
            }
        }
        s=2*n*n+1,t=2*n*n+2;
        add(s,0,2,0);
        add(2*n*n-1,t,2,0);
        printf("%d\n",MinCostFlow(s,t,t+10)-sum);
    }
    return 0;
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

时间: 2024-11-08 20:07:10

hdu 3376 Matrix Again【最大费用流】的相关文章

HDU 2686 Matrix 3376 Matrix Again(费用流)

HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,只是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 思路:拆点,建图,然后跑费用流即可,不过HDU3376这题,极限情况是300W条边,然后卡时间过了2333 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #i

HDU 2686 &amp;&amp; HDU 3376(网络流之费用流)

题目地址:HDU 2686       HDU 3376 这两道题目除了数据大小外是一样的.前者只有30*30,但是后者却成了600*600..本来以为前者代码用到后者会超时,迟迟没敢交,但是感觉能用费用流的话也只能这么做了,于是改了改数组大小就交上去了.还真没超时.. 这题又是一道关于来回最短路的.最大费用可以把费用改成相反数,最后再转成相反数就是最大费用了. 建图思路是拆点,限制每个点只能经过一次.然后将每个点与右边的和下边的连边.源点与汇点要设为2个流量. 不知道为什么用G++叫就一直WA

hdu 2686 Matrix【最大费用流】

Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1792    Accepted Submission(s): 958 Problem Description Yifenfei very like play a number game in the n*n Matrix. A positive integer number

POJ 2135 Farm Tour &amp;&amp; HDU 2686 Matrix &amp;&amp; HDU 3376 Matrix Again 费用流求来回最短路

累了就要写题解,最近总是被虐到没脾气. 来回最短路问题貌似也可以用DP来搞,不过拿费用流还是很方便的. 可以转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1,然后连一条流量为1(花费根据题意来定) 的边来控制每个点只能通过一次. 额外添加source和sink来控制满流为2. 代码都雷同,以HDU3376为例. #include <algorithm> #include <iostream> #include <cstring> #in

hdu 2686 Matrix &amp;&amp; hdu 3367 Matrix Again (最大费用最大流)

Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1394    Accepted Submission(s): 758 Problem Description Yifenfei very like play a number game in the n*n Matrix. A positive integer number

POJ 3422 kaka&#39;s matrix trvals(费用流)

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <cma

POJ训练计划3422_Kaka&#39;s Matrix Travels(网络流/费用流)

解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次只能向右和向下走,走到一个格子上加上格子的数,可以走k次.问最大的和是多少. 思路: 建图:每个格子掰成两个点,分别叫"出点","入点", 入点到出点间连一个容量1,费用为格子数的边,以及一个容量∞,费用0的边. 同时,一个格子的"出点"向它右.下的格子的"入点"连边,容量∞,费用0. 源点向(0,0)的入点连一个容量K的边,(N-1,N-1)的出点向汇点连一

UVa 12534 Binary Matrix 2 zkw费用流模版题

题目链接:点击打开链接 思路: 我们首先假设这个图都是全0的 用n个点代表行,m个点代表列 用源点向行连一个值x 表示每行1的个数,向列连一个y表示每列y个1 则若行i和列j之间流过一个流量就表示 (i,j) 点填了1 那么若原来图中(i,j)点为0 则花费就是1 若原图中(i,j)点是1,则花费是-1 如此枚举x跑个费用流就好了 ==居然把我多年的白书费用流坑掉了... zkw走起啊 #include <stdio.h> #include <string.h> #include

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

POJ 3422 Kaka's Matrix Travels 题目链接 题意:一个矩阵,从左上角往右下角走k趟,每次走过数字就变成0,并且获得这个数字,要求走完之后,所获得数字之和最大 思路:有点类似区间k覆盖的建图方法,把点拆了,每个点有值的只能选一次,其他都是无值的,利用费用流,入点出点之间连一条容量1,有费用的边,和一条容量k - 1,费用0的边,然后其他就每个点和右边和下边2个点连边,然后跑费用流 代码: #include <cstdio> #include <cstring&g

hdu 4862 Jump 上下界费用流

对于每个点拆点成为两个点a,b,连接a到b的上界为1,下界为1的边,保证用过一次且仅一次. 然后若点u可到达点v,则连接即可.建成了一个上下界网络,将下界拆出去,求最大费用最大流就好. #include <stdio.h> #include <iostream> #include <string.h> using namespace std; const int N=800; const int MAXE=200000; const int inf=1<<3