Dijkstra-单源最短路

 

Dijkstra的介绍我就免了,相信点进来的都知道

 

Dijkstra算法和prim算法(求最小生成树)有许多相似之处,区别就是dis数组代表的含义不一样

 

初步学一个算法的时候推荐找一个最基本的题目,别敲别学,不然没什么效果

 

例题    hdu1874畅通工程续

不过这题有点坑:1.重边的处理2.起点与终点相同的情况注意一下就好了

15ms 1504k

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 
 8 #define mem(a) memset(a,0,sizeof(a))
 9 #define ll long long
10 const int maxn = 300;
11 const int inf = 0x3f3f3f3f;
12 int a[maxn][maxn];
13 int dis[maxn];
14 int vis[maxn];
15 int n,m;
16 void dijkstra(int u,int v)
17 {
18     int k = u;
19     mem(vis);
20     for(int i = 0; i < n; i++)
21     {
22         if(i == k)  dis[i] = 0;
23         else dis[i] = inf;
24     }
25     vis[k] = 1;
26     for(int i = 1; i < n; i++)
27     {
28         m = inf;
29         for(int j = 0; j < n; j++)
30         {
31             if(!vis[j] && m > dis[j])
32             {
33                 m = dis[j];
34                 k = j;
35             }
36         }
37         vis[k] = 1;
38         for(int j = 0; j < n; j++)
39             if(!vis[j] && dis[j] > dis[k] + a[k][j])
40                 dis[j] = dis[k] + a[k][j];
41     }
42 
43 }
44 
45 int main()
46 {
47     int u,v,w;
48     while(~scanf("%d",&n))
49     {
50         scanf("%d",&m);
51         for(int i = 0; i < n; i++)
52             for(int j = 0; j < n; j++)
53                 a[i][j] = (i==j?0:inf);
54         for(int i = 0; i < m; i++)
55         {
56             scanf("%d%d%d",&u,&v,&w);
57             if(w < a[u][v])
58                 a[u][v] = a[v][u] = w;
59         }
60         scanf("%d%d",&u,&v);
61         dijkstra(u,v);
62         if(dis[v] == inf) printf("-1\n");
63         else printf("%d\n",dis[v]);
64     }
65     return 0;
66 }
Dijkstra

 附这题的Floyd算法(感兴趣可以了解下)

 

dijkstra的优先队列实现

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef pair<int, int> pii;
 8 const int maxn=1e5+5, maxm=2e5+5;
 9 struct edge
10 {
11     int t, w; edge * nxt;
12     edge(int to, int len, edge * next){ t=to, w=len, nxt=next; }
13 };
14 edge * head[maxn];
15 void add(int u, int v, int len){ head[u]=new edge(v, len, head[u]); }
16 int dis[maxn], v[maxn], n, m, s;
17 
18 void dijkstra(int s)
19 {
20     memset(dis, 0x3f, sizeof dis);                          //sizeof不是一个函数,而是运算符,这种用法是可以的
21     priority_queue<pii, vector<pii>, greater<pii> > Q;      //小根堆 
22     dis[s]=0;
23     Q.push(make_pair(0, s));
24     while(!Q.empty())
25     {
26         int x=Q.top().second;
27         if(v[x]) { Q.pop(); continue;}                      //continue;之前一定要pop掉,否则会死循环 
28         else     { v[x]=true; dis[x]=Q.top().first; Q.pop();}
29 
30         for(edge *p=head[x]; p; p=p->nxt)   if (!v[p->t])   Q.push(make_pair(dis[x]+p->w, p->t));
31     }
32 }
33 
34 int main()
35 {
36     scanf("%d%d%d", &n, &m, &s);
37     for(int i=1, x, y, z; i<=m; i++)    scanf("%d%d%d", &x, &y, &z), add(x, y, z);
38     dijkstra(s);
39     for(int i=1; i<=n; i++)             printf("%d ", dis[i]);
40     printf("\n");
41     return 0;
42 }
Dijkstra

 

posted on 2019-08-16 15:37  By_布衣  阅读(138)  评论(0编辑  收藏  举报

导航