活动介绍

华为OD机试C卷- 快递员的烦恼(Java & JS & Python & C).md-私信看全套OD代码及解析

preview
需积分: 0 1 下载量 94 浏览量 更新于2024-06-09 收藏 5KB MD 举报
### 华为OD机试C卷 - 快递员的烦恼 #### 题目背景与目标 在日常生活中,快递员面临着一个重要的任务:如何有效地将货物送达各个客户手中,同时也要确保能够按时返回投递站。这个问题实际上可以抽象为一个经典的旅行商问题(Traveling Salesman Problem, TSP)的变体。本题的目标是根据提供的信息,为快递员规划一条从投递站出发,经过所有客户,并最终返回投递站的最短路径。 #### 题目描述 **输入格式**: - 第一行输入两个正整数`n`、`m`,其中`n`代表客户的数量,`m`代表快递员额外查找到的客户之间的路线数量。 - 接下来的`n`行,每行包含两个正整数,分别是客户ID和投递站到该客户的距离。 - 再接下来的`m`行,每行包含三个正整数,分别表示两个客户ID以及这两个客户之间的距离。 **输出格式**: - 输出最短路径的总距离。如果不存在这样的路径,则输出-1。 #### 规格 - `0 < n ≤ 10` - `0 ≤ m ≤ 10` - `0 < 客户ID ≤ 1000` - `0 < distance ≤ 10000` #### 解决方案分析 本题虽然表面上看起来像是一个标准的TSP问题,但实际上有所不同。TSP问题通常要求找到经过所有点一次且仅一次的最短路径,而本题则允许重复访问某个点或投递站。这意味着我们可以采用不同的方法来解决此问题。 1. **Floyd-Warshall算法**:这个算法非常适合用来求解所有点对之间的最短路径问题。在这个问题中,我们可以首先使用Floyd-Warshall算法来计算任意两点之间的最短路径,包括客户与客户、客户与投递站之间的距离。 2. **最短路径计算**:一旦得到了所有点对之间的最短路径,我们就可以尝试计算从投递站出发,经过所有客户,再返回投递站的最短路径。由于问题规模较小(最多只有10个客户),可以通过枚举的方式逐一计算可能的路径,并记录最小的总距离。 3. **实现细节**: - 初始化距离矩阵时,除了对角线元素(即自身到自身的距离)设为0之外,其他所有元素应设为正无穷大(表示不可达)。 - 读取输入数据时,将投递站与客户的距离、客户之间的距离存储到距离矩阵中。 - 使用Floyd-Warshall算法更新距离矩阵。 - 遍历所有客户节点,计算从投递站出发到达每个客户再返回投递站的最短路径长度,并选取最小值作为最终答案。 #### 示例代码 (Java) 以下为使用Java语言实现的示例代码: ```java import java.util.Scanner; public class CourierRoutePlanner { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); // 客户数量 int m = scanner.nextInt(); // 路线数量 // 初始化距离矩阵,假设初始距离为正无穷大(表示不可达) int[][] distances = new int[n + 2][n + 2]; // 多加两个位置用于投递站(假设id为0和n+1) for (int i = 0; i <= n + 1; i++) { for (int j = 0; j <= n + 1; j++) { if (i == j) { distances[i][j] = 0; } else { distances[i][j] = Integer.MAX_VALUE; } } } // 读取投递站到客户之间的距离 for (int i = 1; i <= n; i++) { int id = scanner.nextInt(); int dist = scanner.nextInt(); distances[0][i] = dist; // 投递站到客户i distances[i][0] = dist; // 客户i到投递站 } // 读取客户与客户之间的距离 for (int i = 0; i < m; i++) { int id1 = scanner.nextInt(); int id2 = scanner.nextInt(); int dist = scanner.nextInt(); distances[id1][id2] = dist; distances[id2][id1] = dist; // 无向图 } // 假设投递站id为0和n+1,并设置它们之间的距离为0 distances[0][n + 1] = 0; distances[n + 1][0] = 0; // 使用Floyd-Warshall算法求解任意两点间的最短距离 floydWarshall(distances, n + 2); // 计算从投递站到所有客户再回到投递站的最短距离 int minDistance = Integer.MAX_VALUE; for (int i = 1; i <= n; i++) { minDistance = Math.min(minDistance, distances[0][i] + distances[i][n + 1]); } for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { minDistance = Math.min(minDistance, distances[0][i] + distances[i][j] + distances[j][n + 1]); } } // 输出结果 System.out.println(minDistance == Integer.MAX_VALUE ? -1 : minDistance); } private static void floydWarshall(int[][] distances, int n) { for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (distances[i][k] != Integer.MAX_VALUE && distances[k][j] != Integer.MAX_VALUE && distances[i][k] + distances[k][j] < distances[i][j]) { distances[i][j] = distances[i][k] + distances[k][j]; } } } } } } ``` 以上就是针对华为OD机试C卷“快递员的烦恼”题目的详细解析与解决方案。通过Floyd-Warshall算法计算所有点对之间的最短路径,再通过枚举的方式找到最短路径的总距离。这种方法对于本题所设定的数据规模而言是非常高效的。
身份认证 购VIP最低享 7 折!
30元优惠券