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