洛谷 1004 dp或最大费用流
2015-09-01 12:34
405 查看
思路:
dp方法:
设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值。
则转移方程为
dp[i][j][k][l]=max(dp[i-1][j][k-1][l],dp[i][j-1][k-1][l],dp[i-1][j][k][l-1],dp[i][j-1][k][l-1])+map[i][j]+map[k][l];
若两点相同减去一个map[i][j]即可
费用流方法(可以扩展为k条路径,但时间复杂度较高):
源点连接左上角点流量为k、费用为0,右下角点连接汇点流量为k、费用为0,所有点连接右边相邻和下边相邻点流量为k、费用为0,所有点拆点一条流量为1、费用为该
点价值,一条流量为k-1、费用为0。跑最大费用流即可
代码:
dp:
View Code
dp方法:
设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值。
则转移方程为
dp[i][j][k][l]=max(dp[i-1][j][k-1][l],dp[i][j-1][k-1][l],dp[i-1][j][k][l-1],dp[i][j-1][k][l-1])+map[i][j]+map[k][l];
若两点相同减去一个map[i][j]即可
费用流方法(可以扩展为k条路径,但时间复杂度较高):
源点连接左上角点流量为k、费用为0,右下角点连接汇点流量为k、费用为0,所有点连接右边相邻和下边相邻点流量为k、费用为0,所有点拆点一条流量为1、费用为该
点价值,一条流量为k-1、费用为0。跑最大费用流即可
代码:
dp:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> #include <queue> #include <cmath> #include <set> using namespace std; #define N 205 #define M 1005 #define inf 999999999 struct MCF{//min_cost_flow struct Edge{ int v, f, w, next; Edge(){}; Edge(int a,int b,int c,int d){ v=a;f=b;w=c;next=d; } }; int n; int head[N+10]; Edge e[M*2]; int nume; int src, sink; void init(int st, int end,int nn){//初始化 src=st;sink=end;n=nn; memset(head,0,sizeof(head)); nume=1; } void addedge(int u,int v,int c,int w){ e[++nume]=Edge(v,c,w,head[u]); head[u]=nume; e[++nume]=Edge(u,0,-w,head[v]); head[v]=nume; } queue<int>Q; bool visited ; int dis ; int prev , pree ; bool findpath(){ while(!Q.empty()) Q.pop(); Q.push(src); for(int i=0;i<=n;i++) dis[i]=-1; dis[src]=0; visited[src]=true; while(!Q.empty()){ int u=Q.front();Q.pop();visited[u]=false; for(int i=head[u];i;i=e[i].next){ if(e[i].f>0&&dis[u]+e[i].w>dis[e[i].v]){ dis[e[i].v]=dis[u]+e[i].w; prev[e[i].v]=u; pree[e[i].v]=i; if(!visited[e[i].v]){ Q.push(e[i].v); visited[e[i].v]=true; } } } }//printf("111111\n"); if(dis[sink]>0) return true; else return false; } int solve(){ int u=sink; int flow=inf; while(u!=src){ if(e[pree[u]].f<flow) flow=e[pree[u]].f; u=prev[u]; } u=sink; while(u!=src){ e[pree[u]].f-=flow; e[pree[u]^1].f+=flow; u=prev[u]; } return dis[sink]*flow; } int mincostflow(){ int ans=0; while(findpath()){ ans+=solve(); } return ans; } }mcf; int n; int map[10][10]; int x, y, w; main() { int i, j, k; while(scanf("%d",&n)==1){ memset(map,0,sizeof(map)); while(1){ scanf("%d %d %d",&x,&y,&w); if(x==0&&y==0&&w==0) break; map[x][y]=w; } mcf.init(0,n*n*2+1,n*n*2+2); mcf.addedge(0,1,2,0); mcf.addedge(n*n*2,n*n*2+1,2,0); int temp=1; for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ mcf.addedge(temp,temp+n*n,1,map[i][j]); mcf.addedge(temp,temp+n*n,1,0); if(i<n) mcf.addedge(temp+n*n,temp+n,2,0); if(j<n) mcf.addedge(temp+n*n,temp+1,2,0); temp++; } } printf("%d\n",mcf.mincostflow()); } }
View Code
相关文章推荐
- centos下jdk升级
- Angular-UI自动完成输入框AutoComplete[项目中使用]
- 关于JSP页面的验证码简单实现
- 【leetcode每日一题】234.Palindrome Linked List
- hdu oj 1520 Anniversary party(树形dp入门)
- mysql-安装之cmake的编译安装(mysql 5.6以后需要cmake编译安装)
- swift总结1
- mysql-安装之CAMKE编译安装
- 常用正则表达式
- mac ngrok使用
- 解决eclipse+MAVEN提示One or more constraints have not been satisfied.的问题
- 【转载】我的Lean & Agile(精简和敏捷)经历
- Debian root用户无法远程登录
- CUDA入门的学习资料
- JNI编程指南-第十一章 JNI设计思想概述
- php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
- mysql utc 时间格式化
- Fiddler初步---认识Fiddler
- js实现具有高亮显示效果的多级菜单代码
- NYOJ 116 士兵杀敌(二)(线段树区间求和+单点更新)