用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 13:56:09 浏览: 106
以下是使用C++语言实现的代码,采用了Dijkstra算法:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1005;
struct Edge {
int v, w;
Edge(int _v, int _w): v(_v), w(_w) {}
};
vector<Edge> graph[MAXN];
int n, m;
int d[MAXN][MAXN];
int dp[(1<<15) + 5][MAXN];
void Dijkstra(int s) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
memset(d[s], 0x3f, sizeof(d[s]));
d[s][s] = 0;
pq.push({0, s});
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
for (auto &e : graph[u]) {
int v = e.v, w = e.w;
if (d[s][v] > d[s][u] + w) {
d[s][v] = d[s][u] + w;
pq.push({d[s][v], v});
}
}
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
graph[u].push_back(Edge(v, w));
graph[v].push_back(Edge(u, w));
}
for (int i = 0; i < n; i++) {
Dijkstra(i);
}
memset(dp, 0x3f, sizeof(dp));
dp[1][0] = 0;
for (int i = 0; i < (1<<n); i++) {
for (int j = 0; j < n; j++) {
if (dp[i][j] == INF) continue;
for (int k = 0; k < n; k++) {
if (i & (1<<k)) continue;
int nxt = i | (1<<k);
dp[nxt][k] = min(dp[nxt][k], dp[i][j] + d[j][k]);
}
}
}
int ans = INF;
for (int i = 0; i < n; i++) {
ans = min(ans, dp[(1<<n)-1][i] + d[i][0]);
}
if (ans == INF) {
cout << -1 << endl;
} else {
cout << ans << endl;
int cur = (1<<n) - 1, pos = -1;
vector<int> path(n);
for (int i = n-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if ((cur & (1<<j)) && dp[cur][pos] == dp[cur^(1<<j)][j] + d[pos][j]) {
path[i] = j;
cur ^= (1<<j);
pos = j;
break;
}
}
}
for (int i = 0; i < n; i++) {
cout << path[i] << " ";
}
cout << 0 << endl;
}
return 0;
}
```
代码中,我们首先使用Dijkstra算法计算出所有城市之间的最短路径。然后,我们使用状态压缩和动态规划的思想,对从0号城市出发,旅行完每个城市一遍,最后回到0号城市的最小成本进行求解。
具体地,我们用二进制数表示当前已经旅行的城市,用dp[i][j]表示已经旅行过i中二进制位为1的城市,最后一个到达的城市是j的最小成本。我们从0号城市出发,每次加入一个未经过的城市,更新dp数组即可。
最后,我们还需要根据dp数组求出最优路径。我们从最后一个城市开始,倒序推导出路径,具体方法是:对于当前状态cur和最后一个到达的城市pos,我们枚举未经过的城市j,如果从cur到达pos的最小成本等于从cur^(1<<j)到达j的最小成本加上从pos到j的距离,那么就说明从pos到j是最优路径的一部分,将j加入路径中,并更新cur和pos即可。
阅读全文