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. AssemblyVersion、AssemblyFileVersion、AssemblyInformationalVersion 区别

    AssemblyVersion: 几乎保留在.NET内部,AssemblyFileVersion: 就是Windows所见.如果您转到位于目录中的程序集的属性并切换到版本选项卡, 映射到“文件版本”A ...

  2. CarbonCopyCloner 硬盘对拷

    CarbonCopyCloner 硬盘对拷 建议使用 5.1.14-b1以上的版本. 安装文件包 CarbonCopyCloner-5.1.14-b1.dmg ================== E ...

  3. mysql 的使用

    1. 安装 https://dev.mysql.com/downloads/mysql/ 2. 配置 $ vim ~/.bash_profile $ export PATH=$PATH:/usr/lo ...

  4. MMU与cache

    这一快理解的非常浅: MMU 虚拟存储器对内存进行了逻辑上的扩充.比如一个32位的CPU系统,逻辑上的寻址可以达到4GB,但是如果直接对物理地址进行寻址,就要受到主存大小的限制. 在这种条件下,虚拟地 ...

  5. django learn step

    django开发: 1 安装python环境 官网下载后安装 或者安装anacondaconda env list anaconda相关操作: 查看环境 conda env list 创建环境 con ...

  6. 【MySql】Explain笔记

    Explain -- 使用 Explain + SQL 分析执行计划: id:表示此表的执行优先级 id相同,表的执行顺序依次从上往下:                id不同,并且递增,id值越大执 ...

  7. RabbitMQ direct交换器

    1:队列和交换器多次绑定 String[] routekeys={"routekey1","routekey2","routekey3"}; ...

  8. python之变量的数据类型(1)int 、bool 、str 及for循环运用

    一.变量的数据类型(1) 1.int 类型 int类型是整数,常用的有bit_length() 方法 用来返回一个数的二进制长度 2.bool类型 布尔型只有两个值 True,False 有关类型转换 ...

  9. Linux磁盘管理——directory tree与mount point

    参考:/sys 和 /dev 区别 Linux磁盘管理——虚拟文件系统 Directory tree Linux内的所有数据都是以文件的形态来呈现的,所以整个Linux系统最重要的地方就是direct ...

  10. (Linux基础学习)第六章:查询与修改系统的本地化(locale)与键盘布局的设置(locelectl)

    第1节:可查询与修改系统的本地化(locale)与键盘布局的设置[root@centos7 ~]# localectl System Locale: LANG=en_US.UTF-8 VC Keyma ...