7-9 旅游规划
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20
输出样例:
3 40
代码:
#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、