这是求带负边权但是不能有负环的最短路算法,是中国人发明的一种算法吧也是。
首先我们还是用前向星存图,dis[]存当前的最短路径,然后用队列存储待优化的点。首先将起点入队,其次去遍历他所连接的点,如果可以松弛那么只要当前不在队里就将其入队。每一次去用他的队首去去遍历就可以,当队列为空的时候结束。
代码
#include<iostream> #include<cstdio> #include<queue> #define INF 2147483647 #define maxn 10005 #define maxm 500005 using namespace std; int m,n,s; int dis[maxn],head[maxn],vis[maxn]; struct edge{ int next; int w; int v; }e[maxm]; int tot=0; void add(int u,int v,int w){ e[++tot].next=head[u]; head[u]=tot; e[tot].w=w; e[tot].v=v; } queue <int>q; void spfa(){ for(int i=1;i<=n;i++) { dis[i]=INF; vis[i]=0; } q.push(s); dis[s]=0; vis[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].v; if(dis[v]>dis[u]+e[i].w){ dis[v]=dis[u]+e[i].w; if(vis[v]==0){ q.push(v); vis[v]=1; } } } } } int main(){ cin>>n>>m>>s; for(int i=1,x,y,z;i<=m;i++){ cin>>x>>y>>z; add(x,y,z); } spfa(); for(int i=1;i<=n;i++){ cout<<dis[i]<<" "; } return 0; }