Dijkstra算法

问题描述:【单源最短路径问题】给定一个带权图(无负权)和一个指定的顶点V0,求出V0到所有其他各点的最短路径。

算法过程:
本质也是个贪心算法。

①   所有顶点划分为两个集合S和D。初始S集合只有点V0,V0对应的距离值为0;剩余的顶点皆在D集合中,如果存在边<V0,Vi>,则Vi的距离值为此边的权值,否则Vi的距离值为∞

②   从D中选择离源距离值最小的顶点Vm加入到S集合

③   同时以Vm 作为中间顶点,更新距离值

④   重复②③直到D为空(或最小值也为∞)

具体实现:

1.普通实现:更适合稠密图

int min[N];//记录当前最小距离

bool flag[N];//标志是否在集合S中

int pre[N];//如需要打印结点,记录前驱

用一维数组。每次扫描,如需打印路径,增加pre段记录上层。

例:POJ 1847 Tram

2.最小堆优化:比较适合稀疏图,但每次改变距离都要重排堆。

算法复杂度:O(n^2)

附:POJ1847 Tram

View Code
 1 //POJ 1847 Tram Dijkstra
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 #define INF 0xfffffff
 6 #define MIN(x,y) (x < y ? x : y)
 7 int dis[101][101];
 8 int n;
 9 
10 void init_dis()
11 {
12     int t, c;
13     memset(dis, 0xf, sizeof(dis));
14     for (int i = 1; i <= n; i++)
15     {
16         cin >> t;
17         if (t == 0)
18             continue;
19         cin >> c;
20         dis[i][c] = 0;
21         for (int j = 2; j <= t; j++)
22         {
23             cin >> c;
24             dis[i][c] = 1;
25         }
26     }
27     for (int i = 1; i <= n; i++)
28         dis[i][i] = 0;
29 }
30 
31 int Dijktra(int src, int des)
32 {
33     if (src == des) return 0;
34     int minDis[101];//最小距离
35     bool flag[101];
36 
37     memset(minDis, 0xf, sizeof(minDis));
38     memset(flag, 0, sizeof(flag));
39 
40     flag[src] = true;
41     for (int i = 1; i <= n; i++)
42         minDis[i] = dis[src][i];
43 
44     for (int j = 1; j < n; j++)
45     {
46         //取最小
47         int min = 0;
48         for (int i = 1; i <= n; i++)
49             if (!flag[i] && minDis[i] < minDis[min])
50                     min = i;
51         //判断是否取完
52         if (min == des) return minDis[min];
53         if (min == 0) break;
54         flag[min] = true;
55         //更新最短路径长
56         for (int i = 1; i <= n; i++)
57             if (!flag[i])
58                 minDis[i] = MIN(minDis[i], minDis[min]+dis[min][i]);
59     }
60     return -1;
61 }
62 int main(void)
63 {
64     int src, des;
65     cin >> n >> src >> des;
66     init_dis();
67     cout << Dijktra(src, des) << endl;
68     return 0;
69 }

 

posted on 2012-12-12 11:56  澄哥  阅读(216)  评论(0)    收藏  举报

导航