最短路dijkstra算法以及spfa算法

其实这两个,都用了三角形不等式,就是如果通过中介节点可以比原来的还小,那就更新

 (单源最短路)

有个区别就是,dijkstra 是通过优先队列,这样每次都取最小的,每次都取最小的话,最小的不会被其他节点更新,所以只需要一次

也就是说,只要它出过队列,他就可以不用在出一次了,所以我们的标记数组放在出队列的地方,一旦标记过就没有必要再找了

只不过,dijkstra不能负权值

spfa可以负权值

但是它的标记是进queue标记,出queue撤销标记,,,所以每个节点可以标记无数次,,,,所以在有些情况下,这玩意很慢的

注意:

注意Next的应用

注意priority_queue是默认大根堆,,,,,,,,所以存的时候就弄相反数就可以变成小根堆啦

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 
 6 using namespace std;
 7 const int N=10010,M=1000010;
 8 int head[N],ver[N],edge[M],Next[M],d[N],v[N];
 9 int n,m,tot=0;
10 void add(int x,int y,int z){//i->j,edge=z
11     ver[++tot]=y;
12     edge[tot]=z;
13     Next[tot]=head[x];
14     head[x]=tot;//tot是当前的个数,从1开始
15 }
16 priority_queue<pair<int,int> > q;
17 /*
18 Next是该x所对应的下一个数
19 */
20 void dijkstra(){
21     memset(d,0x3f,sizeof(d));
22     memset(v,0,sizeof(v));
23     d[1]=0;
24     q.push(make_pair(0,1));
25     while(q.size()){
26         int x=q.top().second;
27         q.pop();
28         if(v[x]) continue;
29         v[x]=1;
30         for (int i = head[x]; i  ; i=Next[i]) {//Next相当于把x存起来了
31             int y=ver[i],z=edge[i];
32             if(d[y]>d[x]+z){
33                 d[y]=d[x]+z;
34                 q.push(make_pair(-d[y],y));//相反数变小根堆
35             }
36 
37 
38         }
39     }
40 
41 
42 }
43 int main(){
44     cin>>n>>m;//n是点集,m是n边集
45     for (int i = 1; i <= m; i++)
46     {
47         int  x,y,z;
48         cin>>x>>y>>z;
49         add(x,y,z);
50     }
51     dijkstra();
52     for (int i = 1; i <= n; i++)
53     {
54         /* code */
55         cout<<d[i]<<endl;
56     }
57 
58 
59 
60 }
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<string>
 8 #include<vector>
 9 #include<queue>
10 #include<map>
11 #include<set>
12 #include <unordered_set>
13 using namespace std;
14 const int N=10010,M=1000010;
15 int head[N],ver[N],edge[M],Next[M],d[N],v[N];
16 int n,m,tot=0;
17 void add(int x,int y,int z){//i->j,edge=z
18     ver[++tot]=y;
19     edge[tot]=z;
20     Next[tot]=head[x];
21     head[x]=tot;//tot是当前的个数,从1开始
22 }
23 queue<int> q;
24 void spfa(){
25     memset(d,0x3f,sizeof(d));
26     memset(v,0,sizeof(v));
27     d[1]=0;
28     v[1]=1;
29     q.push(1);
30     while(!q.empty()){
31         int x=q.front();
32         q.pop();
33         v[x]=0;
34         for (int i=head[x];i;i=Next[i]) {
35             int y=ver[i];
36             int z=edge[i];
37 
38             if(d[y]>d[x]+z){
39                 d[y]=d[x]+z;
40                 if(!v[y]){
41                     q.push(y);
42                     v[y]=1;
43                 }
44             }
45 
46         }
47     }
48 
49 
50 }
51 
52 int main(){
53     cin>>n>>m;//n是点集,m是n边集
54     for (int i = 1; i <= m; i++)
55     {
56         int  x,y,z;
57         cin>>x>>y>>z;
58         add(x,y,z);
59     }
60     spfa();
61     for (int i = 1; i <= n; i++)
62     {
63         /* code */
64         cout<<d[i]<<endl;
65     }
66 
67 
68 
69 }

 加一个多源最短路的链接https://www.cnblogs.com/zhmlzhml/p/12950663.html

原文地址:https://www.cnblogs.com/zhmlzhml/p/13888343.html