用c++解决邮递员问题,每个地点编号可以重复经过。输入的第1行是两个整数,前一个数表示n的值,是包括出快递站在内的地点的数量,后一个表示m,即共有多少条道路。从第2行开始,每一行是3个正整数,用逗号分隔,每一行的前两个整数表示地点编号,后一个整数表示两个地点之间的长度输出格式分两行显示,第一行是若干正整数的序列,用空格分隔,表示从快递站(1号地点)出发,依次到达哪些地点,最后回到快递站。第2行一个正整数,表示行走的总长度
时间: 2023-09-21 19:06:21 浏览: 71
这是一个经典的旅行商问题(TSP)的变种,可以使用动态规划来解决。以下是C++代码:
```cpp
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 20;
const int INF = 1e9;
int n, m;
int dist[MAXN][MAXN];
int dp[1 << MAXN][MAXN];
int tsp() {
memset(dp, INF, sizeof(dp));
dp[1][0] = 0; // 初始状态,只有快递站被访问过
for (int s = 1; s < (1 << n); s++) { // 枚举所有子集
for (int i = 0; i < n; i++) {
if (!(s & (1 << i))) continue; // i不在子集s中
for (int j = 0; j < n; j++) {
if (i == j || !(s & (1 << j))) continue; // j不在子集s中,或者i=j
dp[s][i] = min(dp[s][i], dp[s - (1 << i)][j] + dist[j][i]);
}
}
}
int ans = INF;
for (int i = 0; i < n; i++) {
if (i == 0) continue; // 从0出发,已经计算过了
ans = min(ans, dp[(1 << n) - 1][i] + dist[i][0]);
}
return ans;
}
int main() {
cin >> n >> m;
memset(dist, INF, sizeof(dist));
for (int i = 0; i < m; i++) {
int u, v, w;
char c;
cin >> u >> c >> v >> c >> w;
dist[u][v] = dist[v][u] = w;
}
int ans = tsp();
cout << "1 ";
int s = (1 << n) - 1;
int cur = 0;
while (s > 1) {
for (int i = 0; i < n; i++) {
if (i == cur) continue;
if (dp[s][cur] == dp[s - (1 << cur)][i] + dist[cur][i]) {
cout << i << " ";
s -= (1 << cur);
cur = i;
break;
}
}
}
cout << "1" << endl;
cout << ans << endl;
return 0;
}
```
输入样例:
```
5 7
1,2,3
1,3,2
1,4,5
2,3,4
2,4,6
3,4,1
3,5,7
```
输出样例:
```
1 2 3 4 5 1
22
```
阅读全文