【算法】祭奠spfa 最短路算法dijspfa

题目链接

本题解来源

 

其他链接

卡spfa的数据组

题解堆优化的dijkstra

题解spfa讲解

 

来自以上题解的图片来自常暗踏阴

使用前向星链表存图

直接用队列优化spfa

struct cmp
{
    bool operator()(int a,int b)
    {
        return dist[a]>dist[b];
    }
};

priority_queue<int,vector<int>,cmp> q;void dijspfa()
{
    q.push(s);
    memset(inq,0,sizeof(inq));
    memset(dist,0x7f,sizeof(dist));
    dist[s]=0;
    while(!q.empty())
    {
        int u=q.top();
        q.pop();inq[u]=0;
        for(int j=first[u];j>0;j=e[j].nxt)
        {
            if(e[j].len+dist[u]<dist[e[j].to])
            {
                dist[e[j].to]=dist[u]+e[j].len;
                if(inq[e[j].to]==0)
                    {
                        q.push(e[j].to);inq[e[j].to]=1;
                    }
            }
        }
    }
}

dijspfa特性

1.判负环

spfa判负环主要用dfs,因为dfs判负环可以及时退出防止超时,

数据强化可以用bfs看下面

题解链接

dijspfa判负环继承spfa的功能

但是可能过不了233

SPjkstra算法--就是本文的dijspfa

 

2.与dij,spfa比较

dij的思想是堆优化后从小到大松弛,每个点只入队一次

spfa的思想是不断修改子节点,使每个点重复入队更新,因此可以判负环

时间差异就在重复入队上

完整代码

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstdio>
 4 #include<cstring>
 5 #define Mx 200001
 6 #define Nx 100001
 7 using namespace std;
 8 struct edge
 9 {
10     int to,nxt,len;
11 }e[Mx];
12 int first[Nx];    int n,m,s;
13 void addstar(int i,int u,int v,int w)
14 {
15     e[i].len=w;
16     e[i].nxt=first[u];
17     e[i].to=v;
18     first[u]=i;
19 }
20 int inq[Nx];
21 int dist[Nx];
22 
23 struct cmp
24 {
25     bool operator()(int a,int b)
26     {
27         return dist[a]>dist[b];
28     }
29 };
30 
31 priority_queue<int,vector<int>,cmp> q;
32 void dijspfa()
33 {
34     q.push(s);
35     memset(inq,0,sizeof(inq));
36     memset(dist,0x7f,sizeof(dist));
37     dist[s]=0;
38     while(!q.empty())
39     {
40         int u=q.top();
41         q.pop();inq[u]=0;
42         for(int j=first[u];j>0;j=e[j].nxt)
43         {
44             if(e[j].len+dist[u]<dist[e[j].to])
45             {
46                 dist[e[j].to]=dist[u]+e[j].len;
47                 if(inq[e[j].to]==0)
48                     {
49                         q.push(e[j].to);inq[e[j].to]=1;
50                     }
51             }
52         }
53     }
54 }
55 int main()
56 {
57     memset(first,0,sizeof(first));
58     cin>>n>>m>>s;
59     for(int i=1;i<=m;++i)
60     {
61         int a,b,c;
62         cin>>a>>b>>c;
63         addstar(i,a,b,c);
64     }
65     dijspfa();
66     for(int i=1;i<=n;++i)
67     {
68         cout<<dist[i]<<" ";
69     }
70     return 0;
71 }
View Code

 

转载于:https://www.cnblogs.com/dormin/p/9976089.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值