初学最短路算法

这几天自学了最短路的


Bellman_Ford和Dijkstra算法,通过一道简单题来回顾一下。

题目来源HDU1874.

Problem Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。

现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
 


Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
 


Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
 


Sample Input
   
   
   
   
3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
 


Sample Output
   
   
   
   
2 -1
解一:Dijkstra算法
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cmath> #include <queue> #include <set> #include <stack> #include <algorithm> #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define mem(a) memset(a, 0, sizeof(a)) #define eps 1e-5 #define M 100005 #define INF 99999 using namespace std ; int vis [ 10006 ]; int a ,b ; int d [M ],w [ 1005 ][ 1005 ];//d记录从起点到I的最短距离,w[I][j]表示i到j的距离// int st ,en ; void Dij () { int v ; for(int i = 0 ;i <a ;i ++) { d [i ]=w [st ][i ];//记录di// } d [st ]= 0 ;//起点到起点的距离为0// vis [st ]= 1 ;//标记起点// for(int i = 0 ;i <a ;i ++)////循环每个点// { int tmp =INF ; for(int j = 0 ;j <a ;j ++)//找到离这个点最近且没被访问的点// { if(tmp >d [j ]&&!vis [j ]) { tmp =d [j ]; v =j ; } } vis [v ]=1//标记这个点// for(int k = 0 ;k <a ;k ++) { if(!vis [k ]) { d [k ]=min (d [k ],d [v ]+w [v ][k ]);//比较从起点直接到k点和起点经过v点到k点的大小// } } } } int main() { while(cin >>a >>b ) { mem (vis ); mem (d ); mem (w ); for(int i = 0 ;i < 202 ;i ++) { for(int j = 0 ;j < 202 ;j ++) { w [i ][j ]=INF ;//首先不知道I到J的距离,将其视为无穷大,后面,没有i到j的直达路线的话,也是无穷大// w [i ][i ]= 0 ; } } for(int i = 0 ;i <b ;i ++) { int aa ,bb ,cc ; cin >>aa >>bb >>cc ; if(w [aa ][bb ]>cc ) { w [aa ][bb ]=cc ;//正确记录i到j的距离// w [bb ][aa ]=cc ; } } cin >>st >>en ; Dij (); if(d [en ]<INF ) { cout <<d [en ]<<endl ; } else { cout << "-1" <<endl ; } } }
解二:Bellman_Ford算法
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cmath> #include <queue> #include <set> #include <stack> #include <algorithm> #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define mem(a) memset(a, 0, sizeof(a)) #define eps 1e-5 #define M 100005 #define INF 0x3f3f3f3f using namespace std ; struct node { int a ,b ,c ; }d [ 2000 ]; int aa ,bb ,st ,en ; int dis [M ]; void BF (int x ,int y ) { for(int i = 0 ;i <aa ;i ++) { dis [i ]=INF ;//起点到i点的距离是无穷大// } dis [st ]= 0 ; for(int i = 0 ;i <aa - 1 ;i ++)//循环aa-1个点// { for(int j = 0 ;j < 2 *bb ;j ++) { if(dis [d [j ].b ]>dis [d [j ].a ]+d [j ].c )//判断从起点到b和起点经过a点到b点大小// { dis [d [j ].b ]=dis [d [j ].a ]+d [j ].c ; } } } if(dis [en ]==INF ) { cout << "-1" <<endl ; } else { cout <<dis [en ]<<endl ; } } int main() { while(cin >>aa >>bb ) { int w ,e ,r ; for(int i = 0 ;i <bb ;i ++) { cin >>w >>e >>r ; d [i ].a =w ; d [i ].b =e ; d [i ].c =r ; d [i +bb ].a =e ; d [i +bb ].b =w ; d [i +bb ].c =r ; } cin >>st >>en ; BF (st ,en ); } }

你可能感兴趣的:(初学最短路算法)