1 View Code
2 1 //SPFA
3 2 #include <iostream>
4 3 #include <queue>
5 4 using namespace std ;
6 5
7 6 const int maxn = 1000 + 10 ;
8 7 const int INF = 0x3ffffff;
9 8 int dis[maxn]; //dis[i],点i到源点的最短路径
10 9
11 10 int map[maxn][maxn];
12 11 int used[maxn]; //used[i],标记点i是否在队列中
13 12
14 13 int SPFA(int start , int end ,int n) //起点,终点,总点数编号为[1,n]
15 14 {
16 15
17 16 dis[start] = 0; //初始化dis[源点]为0,并且源点进队列
18 17
19 18 queue<int>Q;
20 19 Q.push(start);
21 20 used[start] =1 ;
22 21
23 22 while(!Q.empty())
24 23 {
25 24 int head = Q.front();
26 25 Q.pop();
27 26 used[head] = 0; //出队列就解除标记
28 27
29 28 for(int i=1; i<=n; i++)
30 29 {
31 30 if(map[head][i] != INF && dis[head] + map[head][i] < dis[i]) //松弛操作
32 31 {
33 32 dis[i] = dis[head] + map[head][i];
34 33
35 34 if(!used[i]) //i被更新,且不在队列中
36 35 {
37 36 used[i] = 1; //进队就标记
38 37 Q.push(i);
39 38 }
40 39 }
41 40 }
42 41 }
43 42 return dis[end] ; //不能在松弛时找到end就结束,因为有负边可能会找到更短的路径
44 43 }
45 44
46 45
47 46 void init()
48 47 {
49 48 for(int i=0;i<maxn;i++)
50 49 {
51 50 for(int j=0;j<maxn;j++)
52 51 {
53 52 map[i][j]=INF; //初始化图没有边,全部距离为无穷大INF
54 53 }
55 54 dis[i]=INF;
56 55 }
57 56 memset(used,0,sizeof(used));
58 57 }
59 58
60 59
61 60 int main()
62 61 {
63 62 int n,m;
64 63 int a,b,c;
65 64 while(cin>>n>>m,n+m)
66 65 {
67 66 init() ;
68 67 while(m--)
69 68 {
70 69 cin>>a>>b>>c;
71 70 if(c<map[a][b]) //判重边
72 71 {
73 72 // map[a][b]=map[b][a]=c; //无向边
74 73 map[a][b]=c; //SPFA只适用于有向边
75 74 }
76 75 }
77 76
78 77
79 78 cout<< SPFA(1,n,n) <<endl;
80 79
81 80 }
82 81 return 0;
83 82 }