请给出以下问题的完整C++代码实现:给定n个城市(从0到n-1),3元组[A, B, C]表示城市A和城市B之间存在道路,且成本为C。计算从0号城市出发,旅行完每个城市一遍,最后回到0号城市的最小成本与路径。如果不存在最优方案,输出-1. 【输入形式】 第一行有两个数n、m表示n个城市,m条边。 接下来的m行均为空格隔开的三个整数A B C,表示城市A和B之间的成本为C 【输出形式】 最小成本 最小成本对应的路径
时间: 2023-11-22 21:56:45 浏览: 78
一个用C++写的求最短路径的代码
5星 · 资源好评率100%
以下是问题的完整C++代码实现,使用了Dijkstra算法和状态压缩DP:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 16, M = N * (N - 1) / 2, INF = 0x3f3f3f3f;
int n, m;
int g[N][N], d[1 << N][N];
bool st[1 << N][N];
struct Edge {
int a, b, w;
} e[M];
void dijkstra(int start) {
memset(st, 0, sizeof st);
memset(d, 0x3f, sizeof d);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;
d[1 << start][start] = 0;
heap.push({0, 1 << start | start});
while (heap.size()) {
auto t = heap.top();
heap.pop();
int ver = t.second % 16, state = t.second / 16;
if (st[state][ver]) continue;
st[state][ver] = true;
for (int i = 0; i < n; i++) {
if (state >> i & 1) {
for (int j = 0; j < n; j++) {
if (j != i && !(state >> j & 1)) {
int distance = d[state][ver] + g[ver][j];
if (d[state | (1 << j)][j] > distance) {
d[state | (1 << j)][j] = distance;
heap.push({distance, j | (state << 4)});
}
}
}
}
}
}
}
int main() {
cin >> n >> m;
memset(g, 0x3f, sizeof g);
for (int i = 0; i < m; i++) {
int a, b, w;
cin >> a >> b >> w;
g[a][b] = g[b][a] = min(g[a][b], w);
e[i] = {a, b, w};
}
dijkstra(0);
int res = INF;
for (int i = 0; i < (1 << n); i++) {
if (i & 1) {
res = min(res, d[i][0]);
}
}
if (res == INF) {
cout << "-1" << endl;
return 0;
}
cout << res << endl;
vector<int> path;
int state = 1, ver = 0;
while (path.size() < n) {
path.push_back(ver);
for (int i = 0; i < n; i++) {
if (d[state][ver] == d[state | (1 << i)][i] + g[ver][i]) {
state |= 1 << i;
ver = i;
break;
}
}
}
for (auto p : path) cout << p << " ";
cout << endl;
return 0;
}
```
其中,`g` 为邻接矩阵,用于存储每条边的权值。`d` 为状态压缩DP数组,用于存储从起点出发到达某一状态(即经过的城市集合)下某一城市的最短路径长度。`st` 为状态数组,用于记录某一状态下某一城市是否已经访问过。 由于题目要求旅行完每个城市一遍,最终回到起点,所以我们需要从起点出发,状态为 `{1 << start | start}`,即经过的城市集合为 `{start}`。在最后的路径还原中,我们可以通过不断地回溯状态,获取路径上的每一个点。
阅读全文