|  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;
}
 |