SPFA和DIJ求最短路的算法的坑点一直是很多的。经常会让人搞不懂。

易错案例:

用重载运算符来排序,如:

  1. struct cmp {
  2. bool operator ()(int x, int y)
  3. const
  4. {
  5. return dis[x]>dis[y];
  6. }
  7. };

这种做法是不对的,该dis值在堆里不会更新甚至会堵住。

正确案例:

目前只有两种优化算法最可靠,分别为优先队列来优化spfa或dij。

\(SPFA\):

每次从堆中只需要取出到t的最短路最小的元素进行松弛,这样便可以大大缩小松弛的次数,效率从而得到提高。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <queue>
  6. #define int long long
  7. using namespace std;
  8. int n, m, s, a, b, vis[1000100], dis[1000100], cnt, lin[1000100];
  9. struct cym {
  10. int from, to, len, nex;
  11. }e[2000100];
  12. struct cmp{
  13. bool operator () (int x, int y)
  14. {
  15. return dis[x] > dis[y];
  16. }
  17. };
  18. inline void add(int u, int v, int l)
  19. {
  20. e[++cnt].from = u;
  21. e[cnt].to = v;
  22. e[cnt].len = l;
  23. e[cnt].nex = lin[u];
  24. lin[u] = cnt;
  25. }
  26. priority_queue <int, vector <int>, cmp> q;
  27. signed main()
  28. {
  29. scanf("%lld%lld%lld", &n, &m, &s);
  30. for (int i = 1; i <= n; i++)
  31. dis[i] = 2147483647;
  32. for (int i = 1; i <= m; i++)
  33. {
  34. int a, b, c;
  35. scanf("%lld%lld%lld", &a, &b, &c);
  36. add(a, b, c);
  37. }
  38. dis[s] = 0;
  39. q.push(s);
  40. // printf("%d\n", lin[s]);
  41. while(!q.empty())
  42. {
  43. int cur = q.top();
  44. q.pop();
  45. vis[cur] = 0;
  46. for (int i = lin[cur]; i; i = e[i].nex)
  47. {
  48. if (dis[e[i].to] > dis[cur] + e[i].len)
  49. {
  50. dis[e[i].to] = dis[cur] + e[i].len;
  51. if (!vis[e[i].to])
  52. {
  53. q.push(e[i].to);
  54. vis[e[i].to] = 1;
  55. }
  56. }
  57. }
  58. }
  59. for (int i = 1; i <= n; i++)
  60. printf("%lld ", dis[i]);
  61. }

\(DIJ\):

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. using namespace std;
  7. int n, m, s, lin[100010], cnt, a, b, c, vis[100010];
  8. struct cym {
  9. int d, num;
  10. }dis[100100];
  11. struct edge {
  12. int to, len, nex;
  13. }e[200010];
  14. inline void add(int f, int t, int l)
  15. {
  16. e[++cnt].len = l; e[cnt].to = t; e[cnt].nex = lin[f]; lin[f] = cnt;
  17. }
  18. bool operator < (cym a, cym b)
  19. {
  20. return a.d > b.d;
  21. }
  22. priority_queue <cym> q;
  23. int main()
  24. {
  25. scanf("%d%d%d", &n, &m, &s);
  26. for (int i = 1; i <= m; i++)
  27. {
  28. scanf("%d%d%d", &a, &b, &c);
  29. add(a, b, c);
  30. }
  31. for (int i = 1; i <= n; i++)
  32. dis[i].d = 2147483647, dis[i].num = i;
  33. dis[s].d = 0;
  34. q.push(dis[s]);
  35. while(!q.empty())
  36. {
  37. cym cur = q.top(); q.pop();
  38. if (vis[cur.num])
  39. continue;
  40. vis[cur.num] = 1;
  41. for (int i = lin[cur.num]; i; i = e[i].nex)
  42. if (cur.d + e[i].len < dis[e[i].to].d && !vis[e[i].to])
  43. dis[e[i].to].d = e[i].len + cur.d, q.push(dis[e[i].to]);
  44. }
  45. for (int i = 1; i <= n; i++)
  46. printf("%d ", dis[i].d);
  47. }

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. sql 作业创建

    转载:https://jingyan.baidu.com/article/adc81513be3423f722bf7351.html

  2. ASP.NET EF实体主外键关系

    其他解释 https://www.cnblogs.com/wuhenke/archive/2010/08/11/1797307.html 主键.外键 需要删除完外键表才能删除主键表 一对一关系peop ...

  3. R_基本统计分析_06

    summary()提供基础的统计信息 sapply(x,FUN,options)可以指定统计函数 fivenum()可以返回图基五数 Hmisc 中的describe(data)返回变量,观测的变量, ...

  4. ToLua Timer机制

    从一个Bug说起: 在内部试玩时发现有个任务的玩家跟随Npc逻辑挂了. telnet连接到出问题的设备上, 开始搞事情 这个跟随的逻辑是一个Timer驱动的. 这个Timer在主角创建时就会启动. 一 ...

  5. Git使用整理

    [本文由水木桶首发于博客园,原文地址:https://www.cnblogs.com/shuimutong/p/11404664.html,未接允许,严禁转载] 背景 很久之前使用的是svn,直接在E ...

  6. Xcodeproj相关以及删除 多层文件夹、库、资源逻辑

    一.介绍Xcodeproj是CocoaPods用ruby开发的一个插件库,可以用来新建.修改Xcode工程. 二.wiki和资源Xcodeproj wiki   :https://www.rubydo ...

  7. 用weexplus从0到1写一个app(2)-页面跳转和文章列表及文章详情的编写

    说明 结束连续几天的加班,最近的项目终于告一段落,今天抽点时间开始继续写我这篇拖了很久的<用weexplus从0到1写一个app>系列文章.写这篇文章的时候,weexplus的作者已经把w ...

  8. Typescript项目注意点和基本类型介绍

    从typescript源文件到执行的过程 执行者 步骤 说明 TSC 1. TypeScript Source -> TypeScript AST TSC将ts文件转为TS AST(abstra ...

  9. [LeetCode] 581. 最短无序连续子数组 ☆

    描述 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: [2, 6, 4, 8 ...

  10. STM32+IAR 解决Error[Pe147]: declaration is incompatible with "__nounwind __interwork __softfp unsigned

    在IAR中编译STM32工程,遇到 Error[Pe147]: declaration is incompatible with "__nounwind __interwork __soft ...