• 先讲一个为了少打一些代码而滥用继承终于接受慘痛教训的故事。
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <queue>
  4. #include <cstring>
  5. using namespace std;
  6. const int oo = 1000000000, nil = 0;
  7. int N, M, S, T, K, times[1005];
  8. int u[200010], v[200010], w[200010], nxt[200010], pnt[1005], e;
  9. int d[1005];
  10. bool vis[1005], other[1005];
  11. class node
  12. {
  13. public:
  14. int n, dis;
  15. node(int n = 0, int dis = 0) :n(n), dis(dis) {}
  16. protected:
  17. virtual bool operator < (const node& b) const
  18. {
  19. return dis > b.dis;
  20. }
  21. };
  22. struct astar : public node
  23. {
  24. astar(int xn = 0, int xdis = 0)
  25. {
  26. n = xn; dis = xdis;
  27. }
  28. bool operator < (const astar& b) const
  29. {
  30. return dis + d[n] > b.dis + d[b.n];
  31. }
  32. };
  33. void addedge(int a, int b, int c, bool d)
  34. {
  35. u[++e] = a; v[e] = b; w[e] = c;
  36. nxt[e] = pnt[a]; pnt[a] = e; other[e] = d;
  37. }
  38. void init()
  39. {
  40. int a, b, c;
  41. scanf("%d%d", &N, &M);
  42. for(int i = 1; i <= M; ++i)
  43. {
  44. scanf("%d%d%d", &a, &b, &c);
  45. addedge(a, b, c, false);
  46. addedge(b, a, c, true);
  47. }
  48. scanf("%d%d%d", &S, &T, &K);
  49. if(S == T)
  50. {
  51. ++K;
  52. }
  53. }
  54. void getSSSP(int s)
  55. {
  56. memset(d, 0x3f, sizeof(d));
  57. memset(vis, 0, sizeof(vis));
  58. priority_queue <node> Q;
  59. d[s] = 0;
  60. Q.push(node(s, 0));
  61. while(!Q.empty())
  62. {
  63. node t = Q.top();
  64. Q.pop();
  65. vis[t.n] = true;
  66. for(int j = pnt[t.n]; j != nil; j = nxt[j])
  67. {
  68. if((!vis[v[j]]) && (d[v[j]] > t.dis + w[j]) && (other[j]))
  69. {
  70. d[v[j]] = t.dis + w[j];
  71. Q.push(node(v[j], d[v[j]]));
  72. }
  73. }
  74. }
  75. }
  76. void work()
  77. {
  78. getSSSP(T);
  79. memset(times, 0, sizeof(times));
  80. priority_queue <astar> Q;
  81. Q.push(astar(S, 0));
  82. while(!Q.empty())
  83. {
  84. astar t = Q.top();
  85. Q.pop();
  86. ++times[t.n];
  87. if((t.n == T) && (times[t.n] == K))
  88. {
  89. printf("%d\n", t.dis);
  90. return;
  91. }
  92. for(int j = pnt[t.n]; j != nil; j = nxt[j])
  93. {
  94. if(!other[j])
  95. {
  96. Q.push(astar(v[j], t.dis + w[j]));
  97. }
  98. }
  99. }
  100. puts("-1");
  101. }
  102. int main()
  103. {
  104. init();
  105. work();
  106. return 0;
  107. }

然后由于node里的小于号被protected了。stl的priority_queue无法调用之而编译失败。

假设去掉protected。node里的小于号覆盖不掉,又会使astar中的小于号没用导致WA。TUT……

  • 题目来源

id=2449">http://poj.org/problem?id=2449

  • 题目大意

    求一张有向图从S到T的第K短路(边权均为正)。

  • 题解

    首先在反向图中最短路出每一个点到终点的距离,然后利用A*的思想,从起点開始可反复地搜索,估价函数为{当前走过的距离+该点到终点的最短路长度}。当终点T被第K次从堆(优先队列)中取出时,输出答案。

  • 注意细节

    S == T时要把K加上1;

    某结点出队次数超过K时,能够不再考虑。

  • Code

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <queue>
  4. #include <cstring>
  5. using namespace std;
  6. const int oo = 1000000000, nil = 0;
  7. int N, M, S, T, K, times[1005];
  8. int u[200010], v[200010], w[200010], nxt[200010], pnt[1005], e;
  9. int d[1005];
  10. bool vis[1005], other[200010];
  11. struct node
  12. {
  13. int n, dis;
  14. node(int n = 0, int dis = 0) :n(n), dis(dis) {}
  15. bool operator < (const node& b) const
  16. {
  17. return dis > b.dis;
  18. }
  19. };
  20. struct astar
  21. {
  22. int n, dis;
  23. astar(int n = 0, int dis = 0) :n(n), dis(dis) {}
  24. bool operator < (const astar& b) const
  25. {
  26. return dis + d[n] > b.dis + d[b.n];
  27. }
  28. };
  29. void addedge(int a, int b, int c, bool d)
  30. {
  31. u[++e] = a; v[e] = b; w[e] = c;
  32. nxt[e] = pnt[a]; pnt[a] = e; other[e] = d;
  33. }
  34. void init()
  35. {
  36. int a, b, c;
  37. scanf("%d%d", &N, &M);
  38. for(int i = 1; i <= M; ++i)
  39. {
  40. scanf("%d%d%d", &a, &b, &c);
  41. addedge(a, b, c, false);
  42. addedge(b, a, c, true);
  43. }
  44. scanf("%d%d%d", &S, &T, &K);
  45. if(S == T)
  46. {
  47. ++K;
  48. }
  49. }
  50. void getSSSP()
  51. {
  52. memset(d, 0x3f, sizeof(d));
  53. memset(vis, 0, sizeof(vis));
  54. priority_queue <node> Q;
  55. d[T] = 0;
  56. Q.push(node(T, 0));
  57. while(!Q.empty())
  58. {
  59. node t = Q.top();
  60. Q.pop();
  61. vis[t.n] = true;
  62. for(int j = pnt[t.n]; j != nil; j = nxt[j])
  63. {
  64. if((!vis[v[j]]) && (d[v[j]] > t.dis + w[j]) && (other[j]))
  65. {
  66. d[v[j]] = t.dis + w[j];
  67. Q.push(node(v[j], d[v[j]]));
  68. }
  69. }
  70. }
  71. }
  72. void work()
  73. {
  74. getSSSP();
  75. memset(times, 0, sizeof(times));
  76. priority_queue <astar> Q;
  77. Q.push(astar(S, 0));
  78. while(!Q.empty())
  79. {
  80. astar t = Q.top();
  81. Q.pop();
  82. ++times[t.n];
  83. if((t.n == T) && (times[t.n] == K))
  84. {
  85. printf("%d\n", t.dis);
  86. return;
  87. }
  88. if(times[t.n] > K)
  89. {
  90. continue;
  91. }
  92. for(int j = pnt[t.n]; j != nil; j = nxt[j])
  93. {
  94. if(!other[j])
  95. {
  96. Q.push(astar(v[j], t.dis + w[j]));
  97. }
  98. }
  99. }
  100. puts("-1");
  101. }
  102. int main()
  103. {
  104. init();
  105. work();
  106. return 0;
  107. }
  • 再讲一个悲伤的故事:这段代码我一開始把other数组开成了点数,然后RE了4次,另一次忘了删去while(1)……所以一定要养成提前定义常量和认真静态查错的好习惯。

POJ2449题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. Android菜鸟笔记- 获取未安装的APK图标、版本号、包名、名称、是否安装、安装、打开

    周末闲来无事,把Android的基础知识拿出来复习复习,今天主题是<获取未安装的APK图标.版本号.包名.名称.是否安装.跳转安装.打开> 一.获取APK图标 通常读取APK的图标能够用, ...

  2. 4.QList

    #include "mainwindow.h" #include <QApplication> #include <QLabel> #include < ...

  3. UVa512 追踪电子表格中的单元格

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. Linux下安装 php-memcache 扩展

    需要的库:yum install -y libmemcached libmemcached-devel 下载:https://pecl.php.net/package/memcached 安装: un ...

  5. linux进程的有效用户ID

    进程的有效用户ID用于文件访问时的权限检查.通常,有效用户ID等于实际用户ID(也就是你登录是的用户ID),有效组ID等于实际组ID. 我们知道每个文件针对不同的user有不同的读.写.执行权限.当执 ...

  6. 2015 Objective-C 新特性

    Overview 自 WWDC 2015 推出和开源 Swift 2.0 后,大家对 Swift 的热情又一次高涨起来,在羡慕创业公司的朋友们大谈 Swift 新特性的同时,也有很多像我一样工作上依然 ...

  7. 关于<marquee>、<form>、input中的<text>、<password>、<hidden>、<wenbenkuang>、<reset>、<image>、<submit>、<radio>、<checkbox>以及<select><iframe src>的用法

    <html>    <head>        <meta charset="UTF-8">        <title></ ...

  8. spring使用注解开发

    1.准备工作(1)导入common-annotations.jar(2)导入schema文件 文件名为spring-context-2.5.xsd(3)在xml的beans节点中配置 service层 ...

  9. webpack安装,npm WARN optional SKIPPING OPTIONAL DEPENDENCY,npm WARN notsup SKIPPING OPTIONAL DEPENDENCY警告

    npm install webpack -g//全局安装webpack 电脑上安装完后: 其中有两个警告: npm WARN optional SKIPPING OPTIONAL DEPENDENCY ...

  10. (2016北京集训十三)【xsy1531】魔法游戏 - Nim游戏

    题解: 好题!我的结论很接近正解了... 把一个数化成二进制,每次至少要拿走一位,最多全拿走,不能不拿.那么这就是一个经典的Nim问题了,子树异或起来就是根节点的答案,随便递推一下就行了. 代码: # ...