前提:你要知道什么是最短路和什么是图。

下面代码注释已经很完全了,哪里不懂可以问我,我会进行改进

#include<bits/stdc++.h>
#define inf 2147483647              //下文的inf代替为2147483647
using namespace std;
const int maxn=500001;
queue<int>q;
int dis[maxn],vis[maxn],head[maxn],Next[maxn],from[maxn],to[maxn],cost[maxn],cnt;
int n,m,S,x,y,z;
void SPFA(int S)                    //SPFA,S为起点,求出从S出发的所有点的最短路 
{
    for(int i=1;i<=n;i++)dis[i]=inf,vis[i]=0;   //初始dis无限大,经过点清0 
    vis[S]=1;dis[S]=0;q.push(S);    //压入起点 
    while(!q.empty())               //q队列为空退出 
    {
        int u=q.front();q.pop();    //对q队列的队头进行操作 ,u为队头 
        vis[u]=0;                   //将改点标记为不在队列 
        for(int i=head[u];i!=-1;i=Next[i])  //遍历以u为起点的所以边 
        {
            int v=to[i];            //v为改边到达的点 
            if(dis[v]>dis[u]+cost[i])   //如果从u经过i边比原先v最短路小就更新 
            {
                dis[v]=dis[u]+cost[i];  //更新 
                if(vis[v]==0)           //如果v不在队列 
                {
                    q.push(v);          //将v压入队列 
                    vis[v]=1;           //标记v在队列内 
                }
            }
        }
    }
    //跑完SPFA后,dis[i]为以S为起点,到i的最短路 
}
void add(int x,int y,int z)         //前向星建图 
{
    cnt++;                          //表示边数 
    from[cnt]=x;to[cnt]=y;          //from表示cnt边的出发点,to表示cnt边的到达点 
    Next[cnt]=head[x];              //Next指向上一条以x为起点的边
    head[x]=cnt;                    //head[x]表示以x为起点的最后输入的边的编号
    cost[cnt]=z;                    //经过cnt边的费用 
}
int main()
{
    memset(head,-1,sizeof(head));   //初始-1,其实是为边界 
    scanf("%d%d%d",&n,&m,&S);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);                 //对x到y,费用为z建一条边 
    }
    SPFA(S);                        //跑SPFA 
    for(int i=1;i<=n;i++)
    {
        printf("%d ",dis[i]);       //输出 
    }
}

谢谢观赏,希望您能通过本题解学会SPFA!!!

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。