1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
/* Time-stamp:<2010-02-12 22:24:53>
* dijkstra.cpp
* ダイクストラ法.
*/
#include "boost/tuple/tuple.hpp"
#include <climits>
#include <queue>
#include "graph.h"
using namespace boost;
template <class T> // 重みの型
void dijkstra(const Graph &g, // 入力グラフ
const EdgeProperty<T> &weight, // 各辺の重み(非負)
const Vertex &s, // 始点
T *d, // 始点からの最短距離
int *p // 最短経路木における各頂点の親
);
template <class T>
void dijkstra(const Graph &g, const EdgeProperty<T> &weight,
const Vertex &s, T *d, int *p) {
const int size = g.succ.size();
bool *f = new bool[size];
fill_n(d, size, INT_MAX), d[s] = 0, fill_n(p, size, -1);
typedef pair<T, int> Distance;
priority_queue< Distance, vector<Distance>, greater<Distance> > q;
q.push(Distance(0, s));
while (!q.empty()) {
int u;
T d_u;
tie(d_u, u) = q.top(), q.pop();
if (f[u]) continue;
f[u] = true;
foreach (Vertex v, g.succ[u])
if (d[v] > d_u + weight(u, v))
p[v] = u, q.push(Distance(d[v] = d_u + weight(u, v), v));
}
}
int main () {
typedef int Weight;
const int n = 4;
Graph g = Graph(n);
EdgeProperty<Weight> weight;
weight[g.add_edge(0, 1)] = 4;
weight[g.add_edge(0, 2)] = 1;
weight[g.add_edge(1, 3)] = 1;
weight[g.add_edge(2, 1)] = 1;
weight[g.add_edge(2, 3)] = 5;
cout << g << endl;
Weight *dist = new Weight[n];
int *prev = new int[n];
dijkstra<Weight>(g, weight, 0, dist, prev);
for (int i = 0; i < n; ++i)
cout << i << ": " << dist[i] << ", from " << prev[i] << endl;
}
|