解决单源最短路径问题(已固定一个起点,求它到其他所有点的最短路问题)
(1)确定的与起点相邻的点的最短距离,再根据已确定最短距离的点更新其他与之相邻的点的最短距离。
(2)之后的更新不需要再关心最短距离已确定的点
一、矩阵朴素版
二、vector简单版
三、静态邻接表有点复杂版
1 #include <iostream>
2 #include <algorithm>
3 #include <cstring>
4 #include <deque>
5 #include <cstdio>
6 #include <vector>
7 #include <queue>
8 #include <cmath>
9 #define INF 0x3f3f3f3f
10 using namespace std;
11
12 //邻接矩阵
13
14 const int MAXN = 110;
15 int dis[MAXN];
16 int e[MAXN][MAXN];
17 bool vis[MAXN];
18 int N, M;
19
20 void dij()
21 {
22 int p, mis;
23 for(int i = 1; i <= N; i++)
24 dis[i] = e[1][i];
25
26
27 vis[1] = true;
28 dis[1] = 0;
29 for(int i = 1; i < N; i++)
30 {
31 mis = INF;
32 for(int j = 1; j <= N; j++)
33 {
34 if(!vis[j] && dis[j] < mis)
35 {
36 mis = dis[j];
37 p = j;
38 }
39 }
40 vis[p] = true;
41
42 for(int k = 1; k <= N; k++)
43 {
44 if(dis[k] > dis[p] + e[p][k] && !vis[k])
45 dis[k] = dis[p] + e[p][k];
46 }
47 }
48 }
49
50 void init()
51 {
52 for(int i = 1; i <= N; i++)
53 for(int j = 1; j <= N; j++)
54 if(i == j) e[i][j] = 0;
55 else e[i][j] = INF;
56 memset(vis, false, sizeof(vis));
57 }
58 int main()
59 {
60 int a, b, c;
61 while(~scanf("%d%d", &N, &M))
62 {
63 if(N == 0 && M == 0) break;
64 init();
65 while(M--)
66 {
67 scanf("%d%d%d", &a, &b, &c);
68 e[a][b] = c;
69 e[b][a] = c;
70 }
71
72 dij();
73 printf("%d\n", dis[N]);
74 }
75
76 return 0;
77 }
78
79
80
81 //vector 动态邻接表 + 优先队列
82
83 const int MAXN = 1e3 + 50;
84 struct edge
85 {
86 int to, cost;
87 edge(int vo = 0, int vt = 0):
88 to(vo),cost(vt){}
89 };
90
91 vector<edge>G[MAXN];
92 typedef pair<int, int>P;
93 int dis[MAXN];
94 int N, M;
95
96 void init()
97 {
98 for(int i = 1; i <= N; i++)
99 {
100 G[i].clear();
101 dis[i] = INF;
102 }
103
104 }
105 void Dijkstra(int s)
106 {
107 int u, v;
108 priority_queue<P, vector<P>, greater<P> > que;
109 que.push(P(0, s));
110 dis[s] = 0;
111
112 while(!que.empty())
113 {
114 P p = que.top(); que.pop();
115
116 int u = p.second;
117 if(dis[u] < p.first) continue;
118
119 for(int i = 0; i < G[u].size(); i++)
120 {
121 edge v = G[u][i];
122 if(dis[v.to] > dis[u] + v.cost)
123 {
124 dis[v.to] = dis[u] + v.cost;
125 que.push(P(dis[v.to], v.to));
126 }
127 }
128 }
129 }
130
131 int main()
132 {
133 int u, v, c;
134 scanf("%d%d", &N, &M);
135 init();
136 while(M--)
137 {
138 scanf("%d%d", &u, &v, &c);
139 G[u].push_back(edge(v, c));
140 //G[v].push(edge(u, c)); 建无向图
141 }
142
143 //see see
144 /*
145 for(int i = 1; i <= N; i++)
146 {
147 for(int j = 0; j < G[i].size(); j++)
148 printf("%d ", G[i][j].to);
149 puts("");
150 }
151 */
152
153 Dijkstra(1);
154 for(int i = 1; i <= N; i++)
155 printf("%d ", dis[i]);
156 puts("");
157
158 return 0;
159 }
160
161
162
163
164 ///静态邻接表 + 优先队列优化
165
166 const int MAXN = 1e3 + 50;
167 typedef pair<int, int> HeapNode;
168 struct edge
169 {
170 int v, nxt, w;
171 }G[MAXN*100];
172 int head[MAXN], dis[MAXN];
173 int N, M, cnt;
174
175 inline void init()
176 {
177 for(int i = 0; i <= N; i++)
178 head[i] = -1, dis[i] = INF;
179 cnt = 0;
180 }
181
182 inline void add(int from, int to, int we)
183 {
184 G[cnt].w = we;
185 G[cnt].v = to;
186 G[cnt].nxt = head[from];
187 head[from] = cnt++;
188 }
189
190 void dij()
191 {
192 priority_queue<HeapNode, vector<HeapNode>, greater<HeapNode> > heap;
193 dis[1] = 0;
194 heap.push(make_pair(0, 1));
195 while(!heap.empty())
196 {
197 pair<int, int>T = heap.top();
198 heap.pop();
199
200 if(T.first != dis[T.second]) continue;
201
202 for(int i = head[T.second]; i != -1; i = G[i].nxt)
203 {
204 int v = G[i].v;
205 if(dis[v] > dis[T.second] + G[i].w)
206 {
207 dis[v] = dis[T.second] + G[i].w;
208 heap.push(make_pair(dis[v], v));
209 }
210 }
211 }
212 }
213
214 int main()
215 {
216 int a, b, c;
217 while(~scanf("%d%d", &N, &M))
218 {
219 if(N == 0 && M == 0) break;
220 init();
221 while(M--)
222 {
223 scanf("%d%d%d", &a, &b, &c);
224 add(a, b, c);
225 add(b, a, c);
226 }
227
228 dij();
229 printf("%d\n", dis[N]);
230 }
231
232 return 0;
233 }
原文:https://www.cnblogs.com/DWVictor/p/10325952.html