spfa

#include<bits/stdc++.h>
using namespace std;

int n,m,s;//点数,边数,出发点
int u[500005],v[500005],w[500005];
int first[10005],nextt[500005];
int dis[10005];
int book[500005];
queue<int> node;

void clean()
{
    for(int i=1;i<=n;i++)
    {
        dis[i]=2147483647;
    } 
    dis[s]=0;//dis的初始化,当前赋值为0,其余赋值为正无穷
    for(int i=0;i<=500004;i++)
    {
        nextt[i]=-1;
    }
    for(int i=0;i<=10004;i++)
    {
        first[i]=-1;//第一条出边以及每一边的后一边赋值为空 
    }
}

int main()
{
    cin>>n
    >>m
    >>s;
    clean();
    for(int i=1;i<=m;i++)
    {
        cin>>u[i]>>v[i]>>w[i];
        nextt[i]=first[u[i]];//上一边让位,接在当前边后面 
        first[u[i]]=i; //当前边上位 
    }
    node.push(s);
    while(!node.empty())
    {
        int now_node=node.front();
        int k=first[now_node];
        book[now_node]=0;//出队标记 
        node.pop();
        while(k!=-1)//对当前点的每一条出边进行访问 
        {
            if(dis[v[k]]>dis[u[k]]+w[k])//如果松弛成功 
            {
                dis[v[k]]=dis[u[k]]+w[k];//更改最短路 
                if(book[v[k]]==0)//不再队列中 
                {
                    node.push(v[k]);
                    book[v[k]]=1;//打上标记 
                }
            }
            k=nextt[k];//尝试该点的下一条出边 
        }
    }
    for(int i=1;i<=n;i++)
    {
        cout<<dis[i]<<" ";
    }
    return 0;
}

记得入队标记

posted @ 2018-07-21 17:10  前排吃瓜  阅读(223)  评论(0编辑  收藏  举报