SPFA算法模板

来源:互联网 发布:中国人长相 知乎 编辑:程序博客网 时间:2024/06/08 10:02


SPFA算法

优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止


//算法判环并输出最短路径,边从0开始,点都可以struct Edge{    int from,to,dist;};vector<Edge> edges;vector<int> g[1005];//存储from对应的边的标号bool inq[1005];//是否在队列中int d[1005];//源点到各个点的最短路int pre[1005];//最短路的上一条弧int cnt[1005];//进队次数int n,m;//n点的个数,m边的个数int a,b;//求a到b的最短路径并输出a到b的路径void init(){    for(int i=0;i<=n-1;i++)        g[i].clear();    edges.clear();}void addedge(int from,int to,int dist)//边从0开始{    edges.push_back((Edge){from,to,dist});    int num=edges.size();    g[from].push_back(num-1);}bool spfa(int s)//若存在负环返回false{    queue<int> q;    memset(inq,0,sizeof(inq));    memset(cnt,0,sizeof(cnt));    memset(d,0x3f,sizeof(d));    d[s]=0;    inq[s]=1;    q.push(s);    while(!q.empty())    {        int u=q.front();        q.pop();        inq[u]=0;        for(int i=0;i<g[u].size();i++)        {            Edge e=edges[g[u][i]];            if(d[e.to]>d[u]+e.dist)//松弛操作            {                d[e.to]=d[u]+e.dist;                pre[e.to]=g[u][i];                if(!inq[e.to])                {                    q.push(e.to);                    inq[e.to]=1;                    if(++cnt[e.to]>n)//最多松弛n-1次,所有有负环                        return false;//有负环                }            }        }    }    return true;}void print(int s)//输出源点a到s的最短路径{    if(s==a)        return ;    print(edges[pre[s]].from);    cout<<edges[pre[s]].from<<" ";}int main(){    cin>>n>>m;    init();    for(int i=0;i<=m-1;i++)    {        int a,b,c;        cin>>a>>b>>c;        addedge(a,b,c);    }    cin>>a>>b;    if(spfa(a))     {        cout<<d[b]<<endl;        print(b);        cout<<b<<endl;    }    else        cout<<-1<<endl;



0 0
原创粉丝点击