DIJ的优化,和spfa的优化
Posted liuwenyao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DIJ的优化,和spfa的优化相关的知识,希望对你有一定的参考价值。
SPFA和DIJ求最短路的算法的坑点一直是很多的。经常会让人搞不懂。
易错案例:
用重载运算符来排序,如:
struct cmp
bool operator ()(int x, int y)
const
return dis[x]>dis[y];
;
这种做法是不对的,该dis值在堆里不会更新甚至会堵住。
正确案例:
目前只有两种优化算法最可靠,分别为优先队列来优化spfa或dij。
\(SPFA\):
每次从堆中只需要取出到t的最短路最小的元素进行松弛,这样便可以大大缩小松弛的次数,效率从而得到提高。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#define int long long
using namespace std;
int n, m, s, a, b, vis[1000100], dis[1000100], cnt, lin[1000100];
struct cym
int from, to, len, nex;
e[2000100];
struct cmp
bool operator () (int x, int y)
return dis[x] > dis[y];
;
inline void add(int u, int v, int l)
e[++cnt].from = u;
e[cnt].to = v;
e[cnt].len = l;
e[cnt].nex = lin[u];
lin[u] = cnt;
priority_queue <int, vector <int>, cmp> q;
signed main()
scanf("%lld%lld%lld", &n, &m, &s);
for (int i = 1; i <= n; i++)
dis[i] = 2147483647;
for (int i = 1; i <= m; i++)
int a, b, c;
scanf("%lld%lld%lld", &a, &b, &c);
add(a, b, c);
dis[s] = 0;
q.push(s);
// printf("%d\n", lin[s]);
while(!q.empty())
int cur = q.top();
q.pop();
vis[cur] = 0;
for (int i = lin[cur]; i; i = e[i].nex)
if (dis[e[i].to] > dis[cur] + e[i].len)
dis[e[i].to] = dis[cur] + e[i].len;
if (!vis[e[i].to])
q.push(e[i].to);
vis[e[i].to] = 1;
for (int i = 1; i <= n; i++)
printf("%lld ", dis[i]);
\(DIJ\):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int n, m, s, lin[100010], cnt, a, b, c, vis[100010];
struct cym
int d, num;
dis[100100];
struct edge
int to, len, nex;
e[200010];
inline void add(int f, int t, int l)
e[++cnt].len = l; e[cnt].to = t; e[cnt].nex = lin[f]; lin[f] = cnt;
bool operator < (cym a, cym b)
return a.d > b.d;
priority_queue <cym> q;
int main()
scanf("%d%d%d", &n, &m, &s);
for (int i = 1; i <= m; i++)
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
for (int i = 1; i <= n; i++)
dis[i].d = 2147483647, dis[i].num = i;
dis[s].d = 0;
q.push(dis[s]);
while(!q.empty())
cym cur = q.top(); q.pop();
if (vis[cur.num])
continue;
vis[cur.num] = 1;
for (int i = lin[cur.num]; i; i = e[i].nex)
if (cur.d + e[i].len < dis[e[i].to].d && !vis[e[i].to])
dis[e[i].to].d = e[i].len + cur.d, q.push(dis[e[i].to]);
for (int i = 1; i <= n; i++)
printf("%d ", dis[i].d);
以上是关于DIJ的优化,和spfa的优化的主要内容,如果未能解决你的问题,请参考以下文章