使用动态规划思想,利用「备忘录方法」实现对多段图问题进行编程求解。 输入格式: 第1行输入多段图顶点数m和边数n,以一个空格隔开。 依次输入n条边的信息,每行输入一边条的顶点编号及权重,以一个空格隔开。 输出格式: 第1行输出s到t的一条最短路径(路径结点以一个空格隔开),第2行输出此最短路径的长度。c++实现
时间: 2023-11-28 17:47:54 浏览: 59
以下是使用动态规划和备忘录方法求解多段图问题的 C++ 实现代码:
```c++
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1005;
const int INF = 0x3f3f3f3f;
int n, m;
int dist[MAXN], d[MAXN][MAXN];
int pre[MAXN], path[MAXN];
bool vis[MAXN];
void dfs(int u) {
if (u == 1) {
cout << u << " ";
return;
}
dfs(pre[u]);
cout << u << " ";
}
int main() {
memset(d, INF, sizeof(d));
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int a, b, w;
cin >> a >> b >> w;
d[a][b] = w;
}
for (int i = 1; i < n; i++) {
for (int j = i+1; j <= n; j++) {
if (d[i][j] != INF) {
for (int k = i+1; k < j; k++) {
if (d[i][k] != INF && d[k][j] != INF) {
int temp = d[i][k] + d[k][j] + d[k][k];
if (d[i][j] > temp) {
d[i][j] = temp;
pre[j] = k;
}
}
}
}
}
}
memset(dist, INF, sizeof(dist));
dist[1] = 0;
for (int i = 2; i <= n; i++) {
for (int j = 1; j < i; j++) {
if (d[j][i] != INF && dist[j]+d[j][i] < dist[i]) {
dist[i] = dist[j] + d[j][i];
vis[i] = true;
path[i] = j;
}
}
}
cout << "最短路径为: ";
dfs(n);
cout << endl << "最短距离为: " << dist[n] << endl;
return 0;
}
```
其中,`d[i][j]` 表示从顶点 i 到顶点 j 的最短距离,`pre[j]` 表示从顶点 1 到顶点 j 的最短路径上,顶点 j 的前一个顶点,`dist[i]` 表示从顶点 1 到顶点 i 的最短距离,`vis[i]` 表示顶点 i 是否在最短路径上,`path[i]` 表示从顶点 n 到顶点 1 的最短路径上,顶点 i 的后一个顶点。
阅读全文