多段图的最短路
2016-03-26 11:47
218 查看
问题描述:(单向TSP(Unidirectional TSP ,UVa 116))
给一个m行n列的整数矩阵(m<=10,n<=100),从第一列的任意位置出发每次往右,右上,右下走一格,最终达到最后一列。要求经过的整数之和最小。矩阵是环形的,第一行的上一行为最后一行,最后一个行的下一行为第一行。输出路径上的每一列的行号,多解时输出字典序最小的。
分析:
在题目中,每一列就是一个阶段,每个阶段只有3个决策:直行,右上右下。设d[i][j]表示从格子(i,j)出发到最后一列的最小的开销,所有逆推。又因为阶段最优!=最终最优,所以要记录所有的情况,最优解由第一列的最优者决定。所以要用next[i][j]记录当前d[i][j]的最优值是由下一列哪一行推出的;
输入:
5 6
3 4 1 2 8 6
6 1 8 2 7 4
5 9 3 9 9 5
8 4 1 3 2 6
3 7 2 8 6 4
输出:
1 2 3 4 4 5
16
给一个m行n列的整数矩阵(m<=10,n<=100),从第一列的任意位置出发每次往右,右上,右下走一格,最终达到最后一列。要求经过的整数之和最小。矩阵是环形的,第一行的上一行为最后一行,最后一个行的下一行为第一行。输出路径上的每一列的行号,多解时输出字典序最小的。
分析:
在题目中,每一列就是一个阶段,每个阶段只有3个决策:直行,右上右下。设d[i][j]表示从格子(i,j)出发到最后一列的最小的开销,所有逆推。又因为阶段最优!=最终最优,所以要记录所有的情况,最优解由第一列的最优者决定。所以要用next[i][j]记录当前d[i][j]的最优值是由下一列哪一行推出的;
#include <iostream> #include <algorithm> using namespace std; int a[100][100],d[100][100],next[100][100]; int INF = 9999999; int main() { int n,m,i,j,k,first=0; cin>>m>>n; for(i=0;i<m;i++) for(j=0;j<n;j++) cin>>a[i][j]; int ans = INF; for(j=n-1;j>=0;j--) { for(i=0;i<m;i++) { if(j==n-1) { d[i][j]=a[i][j]; } else { int rows[3]={i,i-1,i+1}; if(i==0) rows[1]=m-1; if(i==m-1) rows[2]=0; sort(rows,rows+3); d[i][j]=INF; for(k=0;k<3;k++) { int v = d[rows[k]][j+1] + a[i][j]; if(v < d[i][j]) { d[i][j] = v; next[i][j] = rows[k]; } } } if(j==0 && d[i][j] < ans) { ans = d[i][j]; first = i; } } } cout<<first+1; for(int i=next[first][0],j=1;j < n;j++) { cout<<" "<<i+1; i = next[i][j]; } cout<<endl; cout<<ans<<endl; return 0; }
输入:
5 6
3 4 1 2 8 6
6 1 8 2 7 4
5 9 3 9 9 5
8 4 1 3 2 6
3 7 2 8 6 4
输出:
1 2 3 4 4 5
16
相关文章推荐
- c++函数参数类型-引用
- HD 2048 数塔 DP(简单递推)
- hdu【1520】Anniversary party
- iOS音视频实现边下载边播放
- date 命令
- SVN——项目合作必不可少的工具
- 金庸《倚天屠龙记》中的一个瑕疵
- 抽象类与 接口
- 05 GUPImage混合模式滤镜的使用
- 关于 C++ list 一些使用
- 2016年3月23日作业
- 20160326】十分基础的数论,顺手把球缺体积公式扔这儿
- 集合第三发List接口
- 免费馅饼
- JQuery EasyUI 动态改变表单项的验证守则
- Apache、NGINX支持中文URL
- c++实现归并排序
- 《数据结构与算法分析C++描述》别人总结
- Flying to the Mars
- iOS网络开发中的同步、异步和请求队列