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. 通过c#操作word文档的其他方式

    如果不嫌麻烦可以选择MS的word组件,因为过于庞大复杂.一般都是在无法满足要求的情况下才采用此种方式 参考链接:http://blog.csdn.net/lu930124/article/detai ...

  2. 苏州Uber优步司机奖励政策(12月28日到1月3日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. spring源码-bean之初始化-1

    一.spring的IOC控制反转:控制反转——Spring通过一种称作控制反转(IOC)的技术促进了松耦合.当应用了IOC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查 ...

  4. 157. Unique Characters 【LintCode by java】

    Description Implement an algorithm to determine if a string has all unique characters. Example Given ...

  5. 交换学生 (Foreign Exchange,UVa10763)

    题目描述: 解题思路: 开一个数组,读入一次交换两个数,如果最后数组不变,即符合匹配 #include<iostream> #include<cstdio> #include& ...

  6. 【转】VSstudio中的一些宏

    说明 $(RemoteMachine) 设置为“调试”属性页上“远程计算机”属性的值.有关更多信息,请参见更改用于 C/C++ 调试配置的项目设置. $(References) 以分号分隔的引用列表被 ...

  7. OpenMPI源码剖析3:try_kill_peers 和 ompi_rte_abort 函数

    接着上一篇的疑问,我们说道,会执行 try_kill_peers 函数,它的函数定义在 ompi_mpi_abort.c 下: // 这里注释也说到了,主要是杀死在同一个communicator的进程 ...

  8. HashMap 阅读

    最近研究了一下java中比较常见的map类型,主要有HashMap,HashTable,LinkedHashMap和concurrentHashMap.这几种map有各自的特性和适用场景.使用方法的话 ...

  9. Jedis 与 MySQL的连接线程安全问题

    Jedis的连接是非线程安全的 下面是set命令的执行过程,简单分为两个过程,客户端向服务端发送数据,服务端向客户端返回数据,从下面的代码来看:从建立连接到执行命令是没有进行任何并发同步的控制 pub ...

  10. 开源自动驾驶仿真平台 AirSim (3) - 运行 AirSim

    AirSim 的官方 Github: https://github.com/Microsoft/AirSim 之前配置了很多,终于要让 AirSim 自己跑起来了. 我们需要把 AirSim 这个插件 ...