hdu 2686 Matrix && 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
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.
Each case first line given the integer n (2<n<30)
Than n lines,each line include n positive integers.(<100)
最大费用最大流,搞了好久= =!
题意:
给出一个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 (最大费用最大流)的更多相关文章
- HDU 6118 度度熊的交易计划 最大费用可行流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6118 题意:中文题 分析: 最小费用最大流,首先建立源点 s ,与超级汇点 t .因为生产一个商品需要 ...
- HDU 3395 Special Fish(拆点+最大费用最大流)
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***
题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙, 每个逮捕队伍在每个城市可以选 ...
- HDU 6118 度度熊的交易计划(最小费用最大流)
Problem Description度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个 ...
- HDU 3435 A new Graph Game(最小费用最大流)&HDU 3488
A new Graph Game Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 2686 Matrix 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...
- HDU 2686 Matrix 3376 Matrix Again(费用流)
HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,仅仅是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 ...
- hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- Matrix Again(最大费用最大流)
Matrix Again Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Tota ...
随机推荐
- 长沙Uber优步司机奖励政策(1月4日~1月10日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- JavaScript---复选框反选全选
Script <script type="text/javascript"> /*直接使用document.getElementsByName("c1&quo ...
- 【转载】COM编程入门不得不看的文章 :第一部分 什么是COM,如何使用COM
原文:COM编程入门不得不看的文章 :第一部分 什么是COM,如何使用COM 原文:http://www.codeproject.com/Articles/633/Introduction-to-CO ...
- mongoDB在java上面的应用
1.实际应用过程中肯定不会直接通过Linux的方式来连接和使用数据库,而是通过其他驱动的方式来使用mongoDB 2.本教程只针对于Java来做操作,主要是模拟mongoDB数据库在开发过程中的应用 ...
- JavaSE打开windows文件
第一个参数表示用什么程序打开,第二个参数表示文件的路径 例一: //用记事本打开d:/test.txt文件 Process p = java.lang.Runtime.getRuntime().exe ...
- HBase 数据的多版本特性潜在的意外
HBase做为KeyValue结构存储,在存储上是依照RowKey的字典序进行排序,对于很多应用而言这可能远远不够,好在HBase的数据可以存储多个版本,并且版本可以排序,其理论上最大的版本数目Int ...
- mongdb数据迁移导出与导入
导出: mongoexport --host localhost --port --username un1 --password pwd1 --db db1 --collection col1 -- ...
- andriod学习一
1.Android软件栈 2.Android模拟器 Android SDK 可以通过ADT+Eclipse或者命令行开发,调试,测试应用程序,设备可以使用模拟器或者真实设备, ...
- Shader-水流效果
效果图:(贴图类似于泥石流) 代码: Shader "CookbookShaders/Chapter02/ScrollingUVs" { Properties { _MainTin ...
- python切片技巧
写一个程序,打印数字1到100,3的倍数打印“Fizz”来替换这个数,5的倍数打印“Buzz”,对于既是3的倍数又是5的倍数的数字打印“FizzBuzz” for x in range(101): p ...