最短路径问题-Dijstra
2014-04-06 16:22
183 查看
最短路径问题
问题来源:hdu-3790
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
源代码:
Prim算法与Dijstra算法的区别:Prim是计算最小生成树的算法、Dijkstra是计算最短路径的算法;Prim算法的更新操作更新的cls是已访问集合到未访问集合中各点的距离;Dijkstra算法的更新操作更新的cls是源点到未访问集合中各点的距离,已经访问过的相当于已经找到源点到它的最短距离了;
问题来源:hdu-3790
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
源代码:
#include<stdio.h> #include<string.h> #define MAX 1006 #define INF 999999999 int map[MAX][MAX] , cost[MAX][MAX] , mark[MAX] , dis[MAX] , value[MAX]; //map[i][j]存储双向地图,存储i点到j点的距离 //cost[i][j]存储i点到j点的花费 //mark[i]标志i点手否被更新过 //dis[i]是i点到源点s的最短距离 //value[i]是i点到源点s的最短花费 void Dijstra( int map[][MAX] , int N , int s , int t ); int main( ){ int N , M; int a , b , c , d , s , t; while( ~scanf("%d%d",&N,&M) && N+M!=0 ){ for( int i=1 ; i<=N ; i++ ) for( int j=1 ; j<=N ; j++ ){ map[i][j] = cost[i][j] = INF; //输入前初始化 map[i][i] = cost[i][i] = 0; } for( int i=1 ; i<=M ; i++ ){ scanf("%d%d%d%d",&a,&b,&c,&d); if( c < map[a][b] ){ //重边长度不等的情况 map[a][b] = map[b][a] = c; cost[a][b] = cost[b][a] = d; } //重边相等长度的情况 else if( c==map[a][b] && d<cost[a][b] ){ cost[a][b] = cost[b][a] = d; } } scanf("%d%d",&s,&t); Dijstra(map,N,s,t); } return 0; } void Dijstra( int map[][MAX] , int N , int s , int t ){ //算法思路:最短路径递增,只适用于非负权边 int min , k , last=s; memset( mark , 0 , sizeof( mark ) ); for( int i=1 ; i<=N ; i++ ){ dis[i] = map[s][i]; value[i] = cost[s][i]; } mark[s] = 1; //源点标记 while( 1 ){ for( int i=1 , min=INF ; i<=N ; i++ ){ //寻找下一个dis最短的点 if( mark[i]==0 && dis[i]<min ){ min = dis[k=i]; } } mark[k] = 1; //标记dis最短的边 if( k==t ){ printf("%d %d\n",dis[t],value[t]); return ; } for( int j=1 , min=INF ; j<=N ; j++ ){ //k点来松弛其他节点长度和花费 if( dis[k] + map[k][j] < dis[j] ){ dis[j] = dis[k] + map[k][j]; value[j] = value[k] + cost[k][j]; } else if( dis[k]+map[k][j]==dis[j] && value[k]+cost[k][j]<value[j] ){ value[j] = value[k] + cost[k][j]; } } } }代码分析:采用了Dijstra算法(求单源点到其他点的最短路径),时间复杂度为O(n^2),分为三个步骤:寻找、标记、松弛。
Prim算法与Dijstra算法的区别:Prim是计算最小生成树的算法、Dijkstra是计算最短路径的算法;Prim算法的更新操作更新的cls是已访问集合到未访问集合中各点的距离;Dijkstra算法的更新操作更新的cls是源点到未访问集合中各点的距离,已经访问过的相当于已经找到源点到它的最短距离了;
相关文章推荐
- 最短路径问题(hdu3790,Dijstra)
- hdu3790 最短路径问题 dijstra
- 贪心算法-Dijstra-单源最短路径问题
- 九度 OJ 题目1008:最短路径问题 (Dijstra 算法)
- 街区最短路径问题
- NYOJ 7 街区最短路径问题(数学问题)
- 单源无权最短路径举例——字梯问题
- 彻底弄懂最短路径问题
- HDU3790 最短路径问题+dij算法
- 街区最短路径问题(南阳oj7)(策略问题)
- 实现迷宫问题的所有路径及最短路径程序
- DFS走迷宫问题(非最短路径)
- 南阳oj 街道最短路径问题
- hdu2544 dijkstra最短路径问题
- 数据结构与算法问题 单源最短路径 浙大OJ
- hdu-3790最短路径问题
- 最短路径问题
- 回溯法-bfs--迷宫问题的最短路径
- 学习图算法----最短路径问题
- HDU 3790 - 最短路径问题(优化Dijkstra)