这是一个用来求没有负边权的最短路径算法,复杂度是n^3,经过优先队列优化则是n^2.
算法思想:首先用前向星存储图,用一个node(需要重载运算符)类的priority_queue来存储被松弛的点(vis[i]==0)的的信息,dis[]数组存放当前到达这个点的最短路。其次进行扫描,看堆顶,也就是当前dis[]最小的点,先将其出队,再看其所连的点是否可以进行松弛操作,如果可以松弛,那么更新,并加入优先队列,当队列为空的时候结束。
代码
1 #include<bits/stdc++.h>
2 #define maxn 1000005
3 #define maxm 2100000
4 using namespace std;
5 inline int read()
6 {
7 int x=0,k=1; char c=getchar();
8 while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}
9 while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
10 return x*k;
11 }
12 struct edge{
13 int next;
14 int w;
15 int v;
16 }e[maxm];
17 int n,m,tot=0,s;
18 int head[maxn],vis[maxn],dis[maxn];
19 struct node{
20 int w,now;
21 inline bool operator <(const node &x)const
22 {
23 return w>x.w;//这里注意符号要为'>'
24 }
25 };
26 inline void add(int u,int v,int w){
27 e[++tot].next=head[u];
28 head[u]=tot;
29 e[tot].w=w;
30 e[tot].v=v;
31 }
32 priority_queue<node>q;
33 void dijkstra(){
34 for(int i=1;i<=n;i++) {
35 dis[i]=1234567890;
36 }
37 dis[s]=0;
38 q.push((node){0,s});
39 while(!q.empty()){
40 node x=q.top();
41 int u=x.now;
42 q.pop();
43 if(vis[u]==1) continue;
44 vis[u]=1;
45 for(int i=head[u];i;i=e[i].next){
46 int v=e[i].v;
47 if(dis[v]>dis[u]+e[i].w){
48 dis[v]=dis[u]+e[i].w;
49 q.push((node){dis[v],v});
50 }
51 }
52 }
53 }
54 int main(){
55 n=read(),m=read(),s=read();
56 for(int i=1,x,y,z;i<=m;i++){
57 cin>>x>>y>>z;
58 add(x,y,z);
59 }
60 dijkstra();
61 for(int i=1;i<=n;i++){
62 cout<<dis[i]<<" ";
63 }
64 return 0;
65 }