码迷,mamicode.com
首页 > 编程语言 > 详细

Dijkstra算法模板

时间:2018-10-02 22:20:50      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:起点   hid   ide   display   遍历   http   back   ring   pre   

自己对Dijstra算法的理解是:

  1. 首先输入保存点,边的权值(注意无向图和有向图在保存时的区别)。
  2. 将表示从起点st到顶点 i 的距离的d[ i ]数组的每一个值初始化为INF,令d[st] = 0。
  3.  遍历d[ ]数组的下标 i (即顶点 i)这个操作是通过优先队列来实现的,然后遍历以顶点 i 为起点的边,更新d[ i ]的最小值。
  4. 最后直接访问d[en],即可得到最短距离。

通过模板题来熟悉一下这个算法吧,最短路之HDU2544

技术分享图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <vector>
 6 #include <queue>
 7 #include <algorithm>
 8 #define INF 0x3f3f3f3f
 9 #define FRE() freopen("in.txt","r",stdin)
10 
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> P;//first是距离,second是点的编号
14 const int maxn = 150;
15 int d[maxn];//数组d[i]表示从起点s到顶点 i 的最短距离
16 int n,m;
17 struct edge
18 {
19     edge(int t,int c):to(t),cost(c){}
20     int to;//表示这条边的终点
21     int cost;//该边的权重
22 };
23 vector<edge> G[maxn];//储存以下标i为起点的边
24 priority_queue<P,vector<P>,greater<P> > que;//遍历d[]数组的下标,更新最小值
25 
26 void init()
27 {
28     for(int i = 0; i < maxn; i++)
29         G[i].clear();
30     for(int i = 0; i < m; i++)
31     {
32         int st,en,c;
33         scanf("%d%d%d",&st,&en,&c);
34         G[st].push_back(edge(en,c));//这是个无向图注意储存的方式
35         G[en].push_back(edge(st,c));
36     }
37 }
38 
39 int main()
40 {
41     //FRE();
42     while(scanf("%d%d",&n,&m) && n+m)
43     {
44         init();
45         for(int i = 0; i < maxn; i++)
46             d[i]= INF;
47         d[1] = 0;//起点到起点本身的距离为0
48         que.push(P(0, 1));
49         while(!que.empty())
50         {
51             P p = que.top();
52             que.pop();
53             int v = p.second;
54             if(d[v] < p.first) continue;
55             for(int i = 0; i < G[v].size(); i++)
56             {
57                 edge e = G[v][i];
58                 if(d[e.to] > d[v] + e.cost)
59                 {
60                     d[e.to] = d[v] + e.cost;
61                     que.push(P(d[e.to],e.to));
62                 }
63             }
64         }
65         printf("%d\n",d[n]);
66     }
67     return 0;
68 }
View Code

另外还有一个用二维数组的写法:

技术分享图片
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #define INF 0x3f3f3f3f
 5 
 6 using namespace std;
 7 const int maxn = 100;
 8 
 9 int e[maxn][maxn];
10 int dis[maxn],vis[maxn];
11 int n,m;
12 
13 void init()
14 {
15     for(int i = 1; i <= n; i++)
16     {
17         for(int j = 1; j <= n; j++)
18         {
19             e[i][j] = INF;
20         }
21     }
22     int a,b,c;
23     for(int i = 0; i < m; i++)
24     {
25         scanf("%d%d%d",&a,&b,&c);
26         e[a][b] = c;
27         e[b][a] = c;
28     }
29     for(int i = 1; i <= n; i++)//算出1到各个点的距离
30     {
31         dis[i] = e[1][i];
32         vis[i] = 0;
33     }
34     vis[1] = 1;
35 }
36 
37 void Dij()
38 {
39     for(int i = 1; i <= n; i++)
40     {
41         int mmin = INF;
42         int u;
43         for(int j = 1; j <= n; j++)
44         {
45             if(!vis[j] && dis[j] < mmin)
46             {
47                 mmin = dis[j];
48                 u = j;
49             }
50         }
51         vis[u] = 1;
52         for(int j = 1; j <= n; j++)
53         {
54             if(!vis[j] && dis[j] > e[u][j] + dis[u])
55             {
56                 dis[j] = e[u][j] + dis[u];
57             }
58         }
59     }
60 }
61 
62 int main()
63 {
64     while(scanf("%d%d",&n,&m) && (m + n))
65     {
66         init();
67         Dij();
68         printf("%d\n",dis[n]);
69     }
70     return 0;
71 }
View Code

 

Dijkstra算法模板

标签:起点   hid   ide   display   遍历   http   back   ring   pre   

原文地址:https://www.cnblogs.com/sykline/p/9737817.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!