最短路 spfa+STL

与迪杰斯特拉相同的是spfa也是用来求单源点的最短路径问题,但是,当问题中的边是有向负边的时候,迪杰斯特拉就无能为力了,

而且给我的感觉是spfa如何结合STL来用的话代码比迪杰斯特拉的还要短一点,只是在思路上会比它稍微复杂一点点。spfa的原理:

同样设置一个数组d[maxn]用来保存源点到各点的距离,初始化为无穷打,同时定义一个队列que,初始化为空,然后还要定义一个数组visit[maxn],

用来标记当前的某个点是否在队列当中,初始化为false。算法第一步,把源点加入到队列中,然后用源点去更新源点到它可以到达的点的距离,

如果这个源点到这个点的距离可以被更新,而且队列中没有这个点的话,就把这个点加入到队列中。然后继续从队首弹出一个点,然后同理用这个点

去更新其它的点,重复下去直到队列为空,这时结果就出来了。下面是我A的第一个spfa的代码,用邻接表的,小小的纪念一下。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<deque>
 6 using namespace std;
 7 
 8 typedef struct node
 9 {
10     int d,len;
11     node *next;
12 }Linklist;
13 typedef struct Node
14 {
15     int tot;
16     Linklist *next;
17     Node()
18     {
19         tot = 0;
20         next = NULL;
21     }
22 }linklist;
23 linklist rode[20005];
24 
25 int d[20005],visit[20005];
26 void push(int u,int v,int l)
27 {
28     Linklist *q = new Linklist;
29     q->d = v;
30     q->len = l;
31     q->next = NULL;
32     rode[u].tot++;
33     if(rode[u].next == NULL)
34     {
35         rode[u].next = q;
36         return ;
37     }
38     Linklist *p = rode[u].next;
39     while(p->next)
40     p = p->next;
41     p->next = q;
42 }
43 
44 int main()
45 {
46     int n,m,u,v,l;
47     scanf("%d%d",&n,&m);
48     for(int i = 0;i < m;++i)
49     {
50         scanf("%d%d%d",&u,&v,&l);
51         push(u,v,l);
52     }
53     deque<int> que;
54     deque<int>::iterator iter;
55     que.push_back(1);
56     memset(d,0x3f,sizeof(d));
57     memset(visit,0,sizeof(visit));
58     visit[1] = 1;
59     d[1] = 0;
60     while(!que.empty())
61     {
62         int temp = *(que.begin());
63         que.pop_front();
64         visit[temp] = 0;
65         Linklist *p = rode[temp].next;
66         while(p)
67         {
68             if(d[temp] + p->len < d[p->d])
69             {
70                 d[p->d] = d[temp] + p->len;
71                 if(!visit[p->d])
72                 {
73                     que.push_back(p->d);
74                     visit[p->d] = 1;
75                 }
76             }
77             p = p->next;
78         }
79     }
80     for(int i = 2;i <= n;++i)
81     printf("%d\n",d[i]);
82     return 0;
83 }
View Code

 

转载于:https://www.cnblogs.com/xiaxiaosheng/p/3539093.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值