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的优化的更多相关文章

  1. spfa + slf优化

    最近在练习费用流 , 不是要用spfa吗 ,我们教练说:ns学生写朴素的spfa说出去都让人笑 . QwQ,所以就去学了一下优化 . slf优化就是双向队列优化一下,本来想用lll优化,可是优化后我t ...

  2. SPFA 小优化*2

    /* bzoj 2763 SPFA小优化 循环队列+SLF 顺面改掉自己之前手打qeueu的坏毛病*/ #include<iostream> #include<cstring> ...

  3. HDU 1535 Invitation Cards(SPFA,及其优化)

    题意: 有编号1-P的站点, 有Q条公交车路线,公交车路线只从一个起点站直接到达终点站,是单向的,每条路线有它自己的车费. 有P个人早上从1出发,他们要到达每一个公交站点, 然后到了晚上再返回点1. ...

  4. POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)

    POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意:  圣诞树是由n个节点和e个边构成的,点编号1-n. ...

  5. [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  6. 【最短路径】 SPFA算法优化

    首先先明确一个问题,SPFA是什么?(不会看什么看,一边学去,传送门),SPFA是bellman-ford的队列优化版本,只有在国内才流行SPFA这个名字,大多数人就只知道SPFA就是一个顶尖的高效算 ...

  7. 队列优化dijsktra(SPFA)的玄学优化

    转载:大佬博客 最近想到了许多优化spfa的方法,这里想写个日报与大家探讨下 前置知识:spfa(不带任何优化) 由于使用较多 STLSTL ,本文中所有代码的评测均开启 O_2O2​ 优化 对一些数 ...

  8. SPFA队列优化

    spfa队列优化(用来求最短路) 实现方法: 1.存入图.可以使用链式前向星或者vocter. 2.开一个队列,先将开始的节点放入. 3.每次从队列中取出一个节点X,遍历与X相通的Y节点,查询比对   ...

  9. SPFA的优化

    [为什么要优化] 关于SPFA,他死了(懂的都懂)   进入正题... 一般来说,我们有三种优化方法. SLF优化: SLF优化,即 Small Label First  策略,使用 双端队列 进行优 ...

  10. [MySQL性能优化系列]LIMIT语句优化

    1. 背景 假设有如下SQL语句: SELECT * FROM table1 LIMIT offset, rows 这是一条典型的LIMIT语句,常见的使用场景是,某些查询返回的内容特别多,而客户端处 ...

随机推荐

  1. docker-compose 单机容器编排

    docker-compose用来在单机上编排容器(定义和运行多个容器,使容器能互通) docker-compose将所管理的容器分为3层结构:project  service  container d ...

  2. Spark 系列(十三)—— Spark Streaming 与流处理

    一.流处理 1.1 静态数据处理 在流处理之前,数据通常存储在数据库,文件系统或其他形式的存储系统中.应用程序根据需要查询数据或计算数据.这就是传统的静态数据处理架构.Hadoop 采用 HDFS 进 ...

  3. 未能加载文件或程序集system.web.extensions解决方法

    发现未能加载文件或程序集的错误,这是由于我的机器上没有安装Ajax的原因.问题解决后,整理如下:表现:1."System.Web.Extensions, Version=1.0.61025.0, Cu ...

  4. wc命令——Linux系统高效数据统计工具

    wc(world count)是一个统计文件字词,字节,行数的Linux命令,它可以帮我们非常方便的统计以上信息. 主要参数 常见参数如下: -c 统计字节数. -l 统计行数. -m 统计字符数.这 ...

  5. 四 python中关于OOP的常用术语

    抽象/实现 抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于 绘程序结构,从而实现这种模型.抽象不仅包括这种模型的数据属性,还定义了这些数据的接口. 对某种抽象的实现 ...

  6. js 数组 去重 算法(转载)

    以下内容可能有重复部分,项目有用上,但还没来得急整理和验证. 一:https://www.cnblogs.com/jiayuexuan/p/7527055.html 1.遍历数组法 它是最简单的数组去 ...

  7. 限制mongoDB内存的方法

    docker运行MongoDB,针对于docker容器来进行内存资源的限制 修改MongoDB的运行配置文件,并且重启mongodb storage: dbPath: /var/lib/mongodb ...

  8. 设置Django生产环境系统重启后的自动启动项

    前面,作者已经介绍了把Django部署到生产环境中的主要方法,现在我们来看一下如何设置项目开机启动. 在把Django项目部署到生产环境中时,我们前面使用安装包和源码安装了Nginx.uwsgi.re ...

  9. Java注解annotation : invalid type of annotation member

    前言 首先,关于注解的介绍就不多描述了,网上有很多这方面的资料.本文主要是介绍如何处理标题中遇到的问题:invalid type of annotation member ? 正文 Annotatio ...

  10. mysql in条件查询到底会不会用到索引

    MySQL 的 in 查询在 5.5 以上的版本中存储引擎都是 innodb 的,正常情况下会走索引的!至于 MyISAM 没试过! 如果是 5.5 之前的版本确实不会走索引的,在 5.5 之后的版本 ...