SPFA

这是求带负边权但是不能有负环的最短路算法,是中国人发明的一种算法吧也是。

首先我们还是用前向星存图,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;
}

相关推荐