7-9 旅游规划
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
1 2 3 4 5 6 | 4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20 |
输出样例:
1 | 3 40 |
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include <stdio.h> #include <stdlib.h> #include <iostream> #include <set> #include <queue> int G[502][502][2]={0}; bool visited[502]={ false }; int dis[502],cost[502]; int n,m,s,d,x,y,l,c; void Dijkstra( int start){ dis[start]=0; cost[start]=0; for ( int i=0;i<n;i++){ int u=-1,INF=999999; for ( int j=0;j<n;j++){ if (visited[j]== false &&dis[j]<INF){ INF=dis[j]; u=j; } } // printf("%d\n",u); if (u==-1) return ; visited[u]= true ; for ( int j=0;j<n;j++){ if (visited[j]== false &&G[u][j][0]>0){ // printf("%d %d %d %d\n",j,dis[u],G[u][j][0],dis[j]); if (dis[u]+G[u][j][0]<dis[j]){ dis[j]=dis[u]+G[u][j][0]; cost[j]=cost[u]+G[u][j][1]; } else if (dis[u]+G[u][j][0]==dis[j]&&cost[u]+G[u][j][1]<cost[j]){ cost[j]=cost[u]+G[u][j][1]; } } } } } int main(){ scanf( "%d%d%d%d" ,&n,&m,&s,&d); for ( int i=1;i<=m;i++){ scanf( "%d%d%d%d" ,&x,&y,&l,&c); G[x][y][0]=G[y][x][0]=l; G[x][y][1]=G[y][x][1]=c; } for ( int i=0;i<502;i++){ dis[i]=999999; cost[y]=999999; } Dijkstra(s); printf( "%d %d" ,dis[d],cost[d]); return 0; } |
结论:
1、Floyd求最短路径问题(是一种动态规划算法)的优点:适用于多源最短路径、边权可正可负、由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法(求出起点为V个点中任意点的最短路径,因此是V次),也要高于执行|V|次SPFA算法。
但是此题使用Floyd算法(O(n^3))求最短路径会超时
2、此题路径权值有两个,分别是长度和过路费,先考虑长度,后考虑或路费,这个要求对最短路径的算法稍作修改来实现。
3、

· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现