用c++解决邮递员问题,输入的第1行是两个整数,前一个数表示n的值,是包括出快递站在内的地点的数量,后一个表示m,即共有多少条道路。从第2行开始,每一行是3个正整数,用逗号分隔,形如“x,y,z”,表示两个地点之间道路长度,x和y是地点编号,z是长度。所有道路信息按首个地点x升序排列,x相同者再按y排序。输出格式分两行显示,第一行是若干正整数的序列,用空格分隔,表示从快递站(1号地点)出发,依次到达哪些地点,最后回到快递站。第2行一个正整数,表示行走的总长度。
时间: 2023-09-18 17:15:46 浏览: 565
中国邮路问题邮递员问题欧拉路径图论C++
5星 · 资源好评率100%
以下是C++解决邮递员问题的代码:
```c++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> graph(n + 1, vector<int>(n + 1, INF));
for (int i = 0; i < m; i++) {
int x, y, z;
char comma;
cin >> x >> comma >> y >> comma >> z;
graph[x][y] = graph[y][x] = z;
}
// Floyd算法
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]);
vector<int> path;
int total = 0;
// 贪心算法:每次选择距离当前点最近但未走过的点
int cur = 1; // 当前所在的点
vector<bool> visited(n + 1, false); // 标记每个点是否已经走过
visited[1] = true; // 快递站(1号地点)已经走过
path.push_back(1); // 将快递站(1号地点)加入路径中
for (int i = 0; i < n - 1; i++) {
int next = -1, dist = INF;
for (int j = 1; j <= n; j++) {
if (!visited[j] && graph[cur][j] < dist) {
next = j;
dist = graph[cur][j];
}
}
visited[next] = true;
path.push_back(next);
total += dist;
cur = next;
}
// 回到快递站(1号地点)
path.push_back(1);
total += graph[cur][1];
// 输出结果
for (int i = 0; i < path.size(); i++)
cout << path[i] << " ";
cout << endl << total << endl;
return 0;
}
```
算法思路:
首先,根据输入的道路信息构建邻接矩阵 `graph`,其中 `graph[i][j]` 表示从地点 `i` 到地点 `j` 的路径长度,若不存在这条路径则设为一个极大值。
然后,使用 Floyd 算法求出任意两点之间的最短路径,即对于任意 $i,j\in[1,n]$,计算 `graph[i][j]` 的最小值。
接着,使用贪心算法求解最优路径。从快递站(1号地点)开始,每次选择距离当前点最近但未走过的点,直到走过所有点并回到快递站。
最后,输出路径和行走总长度。
阅读全文