dijkstra

这是一个用来求没有负边权的最短路径算法,复杂度是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 }

 

posted @ 2019-10-24 22:39  毛炯人  阅读(251)  评论(0编辑  收藏  举报