这是求带负边权但是不能有负环的最短路算法,是中国人发明的一种算法吧也是。
首先我们还是用前向星存图,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;
}