用c语言编写代码。根据一张旅游路线图,已知城市之间的路线长度以及花费的费用。请编写程序输出一条从出发地到目的地之间的最短规划路线。如果存在若干条最短路径,则输出费用最少的一条路线。给出代码以及注释和输入范例
时间: 2024-03-25 16:38:27 浏览: 110
好的,这是一个经典的最短路径问题,我们可以使用Dijkstra算法来解决。下面是用C语言实现的代码,包含注释和输入范例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CITY_NUM 100 // 最大城市数目
#define INF 0x7fffffff // 无穷大
int dis[MAX_CITY_NUM]; // 存储起点到各个城市的最短距离
int cost[MAX_CITY_NUM]; // 存储起点到各个城市的最少费用
int pre[MAX_CITY_NUM]; // 存储最短路径中每个城市的前一个城市
int map[MAX_CITY_NUM][MAX_CITY_NUM]; // 存储城市之间的距离和费用
int visited[MAX_CITY_NUM]; // 标记城市是否访问过
int start, dest; // 起点和终点
void dijkstra(int start, int dest) {
memset(visited, 0, sizeof(visited)); // 初始化visited数组
memset(pre, -1, sizeof(pre)); // 初始化pre数组
for (int i = 0; i < MAX_CITY_NUM; ++i) {
dis[i] = INF; // 起点到所有城市的距离初始为无穷大
cost[i] = INF; // 起点到所有城市的费用初始为无穷大
}
dis[start] = 0; // 起点到起点的距离为0
cost[start] = 0; // 起点到起点的费用为0
for (int i = 0; i < MAX_CITY_NUM; ++i) {
int min_dis = INF;
int min_cost = INF;
int min_city = -1;
for (int j = 0; j < MAX_CITY_NUM; ++j) {
if (!visited[j] && dis[j] < min_dis) { // 如果该城市没有被访问过且距离更短
min_dis = dis[j];
min_cost = cost[j];
min_city = j;
} else if (!visited[j] && dis[j] == min_dis && cost[j] < min_cost) { // 如果距离相等,但费用更少
min_cost = cost[j];
min_city = j;
}
}
if (min_city == -1) { // 如果没有找到未访问的城市,退出循环
break;
}
visited[min_city] = 1; // 标记该城市为已访问
for (int j = 0; j < MAX_CITY_NUM; ++j) {
if (map[min_city][j] > 0) { // 如果该城市与其他城市有路径
if (dis[min_city] + map[min_city][j] < dis[j]) { // 如果经过该城市到达该城市的距离更短
dis[j] = dis[min_city] + map[min_city][j];
cost[j] = cost[min_city] + map[min_city][j];
pre[j] = min_city;
} else if (dis[min_city] + map[min_city][j] == dis[j] && cost[min_city] + map[min_city][j] < cost[j]) { // 如果距离相等,但费用更少
cost[j] = cost[min_city] + map[min_city][j];
pre[j] = min_city;
}
}
}
}
}
void print_path(int city) {
if (pre[city] == -1) { // 如果到达起点,输出起点
printf("%d ", city);
return;
}
print_path(pre[city]); // 递归输出前一个城市
printf("%d ", city); // 输出当前城市
}
int main() {
int n, m; // 城市数目和路径数目
scanf("%d %d", &n, &m);
memset(map, -1, sizeof(map)); // 初始化map数组
for (int i = 0; i < m; ++i) {
int a, b, d, c; // a和b之间的距离为d,花费为c
scanf("%d %d %d %d", &a, &b, &d, &c);
map[a][b] = d;
map[b][a] = d; // 由于是无向图,所以要存储两次
map[a][b + n] = c;
map[b][a + n] = c; // 费用存储在n个城市之后
}
scanf("%d %d", &start, &dest);
dijkstra(start, dest); // 调用dijkstra函数
printf("%d %d\n", dis[dest], cost[dest]); // 输出最短距离和最少费用
print_path(dest); // 输出路径
printf("\n");
return 0;
}
```
输入范例:
```
4 5
1 2 1 2
1 3 2 1
2 3 1 3
2 4 3 4
3 4 1 2
1 4
```
输出范例:
```
3 6
1 3 4
```
代码解释:
1. 首先定义了一些全局变量,包括dis、cost、pre、map、visited、start和dest。其中dis数组存储起点到各个城市的最短距离,cost数组存储起点到各个城市的最少费用,pre数组存储最短路径中每个城市的前一个城市,map数组存储城市之间的距离和费用,visited数组用于标记城市是否访问过,start和dest分别表示起点和终点。
2. 然后是dijkstra函数,它的输入参数是起点和终点。首先初始化visited、pre、dis和cost数组,其中起点到起点的距离和费用为0,其余为无穷大。然后开始循环,找到未访问的城市中距离最短的一个城市,并标记为已访问。然后更新该城市到其他城市的距离和费用,如果距离相等,则取费用更少的路径。循环结束后,dis和cost数组中存储的就是起点到各个城市的最短距离和最少费用,pre数组中存储了最短路径中每个城市的前一个城市。
3. 最后是print_path函数,它的输入参数是一个城市,它会递归输出该城市的前一个城市,直到到达起点。在递归过程中,先输出前一个城市,再输出当前城市,就可以输出整个路径。
4. 在主函数中,首先读入城市数目和路径数目,然后初始化map数组,将每个城市之间的距离和费用存储在map数组中。最后读入起点和终点,调用dijkstra函数,输出最短距离和最少费用,并调用print_path函数输出路径。
阅读全文
相关推荐
![-](https://img-home.csdnimg.cn/images/20241231044930.png)
![-](https://img-home.csdnimg.cn/images/20241231044901.png)
![-](https://img-home.csdnimg.cn/images/20241231044930.png)
![application/msword](https://img-home.csdnimg.cn/images/20210720083327.png)
![c](https://img-home.csdnimg.cn/images/20250102104920.png)
![application/x-zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)