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 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
 
Author
yifenfei
 
Source
 
Recommend
yifenfei   |   We have carefully selected several similar problems for you:  3376 1533 3416 3081 2448 
 

最大费用最大流,搞了好久= =!

题意:

给出一个n*n的矩阵,求(1,1)到(n,n)的两条不想交不重叠的路径,使经过的点的和最大。

开始想到的是DP,后来发现了可以用多线程DP实现:

参考:http://www.cnblogs.com/jackge/archive/2013/04/17/3025628.html

让两个进程同时进行,枚举步数K,当x1==x2||y1==y2时跳过,得状态转移方程:

dp(k, x1, y1, x2, y2) = max(dp(k-1, x1-1, y1, x2-1, y2), dp(k-1, x1-1, y1, x2, y2-1), dp(k-1, x1, y1-1, x2-1, y2), dp(k-1, x1, y1-1,x2, y2-1))

+ data(x1, y1) + data(x2, y2) ;

由于只能走右或下,所以坐标满足x+y=k。这样就能降低维数为3维,方程:

dp(k, x1, x2) = max(dp(k-1, x1, x2), dp(k-1, x1-1, x2), dp(k-1, x1, x2-1), dp(k-1, x1-1, x2-1)) + data(x1, k-x1) + data(x2, k-x2) ;

code:

 //31MS    1196K    880 B    G++
#include<stdio.h>
#include<string.h>
#define N 50
int p[N][N];
int dp[*N][N][N];
int max(int a,int b)
{
return a>b?a:b;
}
int Max(int a,int b,int c,int d)
{
return max(a,max(b,max(c,d)));
}
int main(void)
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(dp,,sizeof(dp));
for(int i=;i<n;i++)
for(int j=;j<n;j++)
scanf("%d",&p[i][j]);
for(int k=;k<*n-;k++)
for(int i=;i<n;i++)
for(int j=;j<n;j++){
if(i==j) continue;
dp[k][i][j]=Max(dp[k-][i][j],dp[k-][i-][j],dp[k-][i][j-],dp[k-][i-][j-]);
dp[k][i][j]+=p[i][k-i]+p[j][k-j];
}
int ans=max(dp[*n-][n-][n-],dp[*n-][n-][n-])+p[][]+p[n-][n-];
printf("%d\n",ans);
}
return ;
}

先拆点构图,每个点一分为二,保证了只经过一次,其实网络流的方法就已经解决了这个问题,其次构图时注意把数变为负数,求最小费用最大流。

其实构好图后就是直接套模板了,所以构图的时候注意点,处理一下(1,1)和(n,n)两个点,因为会经过两次。

code:

 //31MS    384K    2396 B    G++
#include<stdio.h>
#include<string.h>
#include<queue>
#define N 2005
#define inf 0x7ffffff
using namespace std;
struct node{
int u,v,c,w;
int next;
}edge[*N];
int vis[N];
int Head[N],d[N],edgenum;
int pre[N],path[N];
void addedge(int u,int v,int c,int w)
{
edge[edgenum].u=u;
edge[edgenum].v=v;
edge[edgenum].c=c;
edge[edgenum].w=w;
edge[edgenum].next=Head[u];
Head[u]=edgenum++; edge[edgenum].u=v;
edge[edgenum].v=u;
edge[edgenum].c=;
edge[edgenum].w=-w;
edge[edgenum].next=Head[v];
Head[v]=edgenum++;
}
int SPFA(int s,int e)
{
memset(vis,,sizeof(vis));
memset(pre,-,sizeof(pre));
for(int i=;i<=e;i++)
d[i]=inf;
queue<int>Q;
d[s]=;
vis[s]=;
Q.push(s);
while(!Q.empty()){
int u=Q.front();
Q.pop();
vis[u]=; //这里WA了好多次
for(int i=Head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
int w=edge[i].w;
if(edge[i].c> && d[v]>d[u]+w){
pre[v]=u;
path[v]=i;
d[v]=d[u]+w;
if(!vis[v]){
vis[v]=;
Q.push(v);
}
}
}
}
if(pre[e]!=-) return ;
return ;
}
int cost_min_flow(int s,int e)
{
int cost=;
while(SPFA(s,e)){
int minc=inf;
for(int i=e;i!=s;i=pre[i]){
minc=minc<edge[path[i]].c?minc:edge[path[i]].c;
}
for(int i=e;i!=s;i=pre[i]){
edge[path[i]].c-=minc;
edge[path[i]^].c+=minc;
cost+=minc*edge[path[i]].w;
}
}
return cost;
}
int main(void)
{
int n;
int p[][];
while(scanf("%d",&n)!=EOF)
{
edgenum=;
memset(Head,-,sizeof(Head));
int k=n*n;
int s=,e=*k+;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
scanf("%d",&p[i][j]);
addedge(j+(i-)*n,k+j+(i-)*n,,-p[i][j]);
if(j!=n) addedge(k+j+(i-)*n,j++(i-)*n,,);
if(i!=n) addedge(k+j+(i-)*n,j+i*n,,);
}
addedge(s,,,);
addedge(,k+,,);
addedge(*k,e,,);
addedge(k,*k,,);
printf("%d\n",-cost_min_flow(s,e));
}
return ;
}

hdu 2686 Matrix && hdu 3367 Matrix Again (最大费用最大流)的更多相关文章

  1. HDU 6118 度度熊的交易计划 最大费用可行流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6118 题意:中文题 分析: 最小费用最大流,首先建立源点 s ,与超级汇点 t .因为生产一个商品需要 ...

  2. HDU 3395 Special Fish(拆点+最大费用最大流)

    Special Fish Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  3. hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***

    题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙,          每个逮捕队伍在每个城市可以选 ...

  4. HDU 6118 度度熊的交易计划(最小费用最大流)

    Problem Description度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个 ...

  5. HDU 3435 A new Graph Game(最小费用最大流)&amp;HDU 3488

    A new Graph Game Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. hdu 2686 Matrix 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...

  7. HDU 2686 Matrix 3376 Matrix Again(费用流)

    HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,仅仅是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 ...

  8. hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  9. Matrix Again(最大费用最大流)

    Matrix Again Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Tota ...

随机推荐

  1. 北京Uber优步司机奖励政策(高峰期5倍奖励)(12月7日)

    用户组:人民优步及电动车(适用于12月7日) 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http ...

  2. Mybatis之关联查询及动态SQL

    前言 实际开发项目中,很少是针对单表操作,基本都会联查多表进行操作,尤其是出一些报表的内容.此时,就可以使用Mybatis的关联查询还有动态SQL.前几篇文章已经介绍过了怎么调用及相关内容,因此这里只 ...

  3. requests,lxml爬启信宝

    首先, 添加requests模块: 然后, 添加lxml模块: 启信宝登录抓包: QiXinBao.py: import requestsfrom lxml import etree loginUrl ...

  4. mysql 各种存储引擎的特点

  5. python 终极篇 --- form组件 与 modelForm

                                                           form组件                                       ...

  6. 【转】《王者荣耀》技术总监复盘回炉历程:没跨过这三座大山,就是另一款MOBA霸占市场了

    如今已经大获市场成功的<王者荣耀>一直是业内各方关注的对象,而我们也知道这款产品在成为国民级游戏之前,也遇到过一段鲜有人知的调优期.也就是在2015年8月18号正式不删档测试版本推出之后, ...

  7. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(2)

    @白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ     需求: 1.梳理FexpressionInput和Output的编译和链接(套路和逻辑目的) 2.如何做到节点编译 ...

  8. Java学习笔记-12.传递和返回对象

    1.Clone()方法产生一个object,使用方法后必须产生的object赋值. Vector v2 = (Vector)v.clone(); 2.Clone()方法在object中是保护类型方法, ...

  9. 我的linux操作习惯

    标签(空格分隔): ubuntu 最佳操作 用linux随时可能会有宕机的危险,谁知道我哪会神经病犯了呢.用deepin宕机的可能性会更高的,所以我才不得不安装一个windows做备份,然后把数据备份 ...

  10. URAL 1519 Formula 1(插头DP,入门题)

    Description Background Regardless of the fact, that Vologda could not get rights to hold the Winter ...