码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3040 最短路 (堆优化dijkstra)

时间:2014-08-06 11:40:41      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:io   数据   时间   log   学习   简单   优化   on   

这题不是裸的最短路么?但是一看数据范围就傻了。点数10^6,边数10^7。这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了。但是,平时写dijkstra时为了偷懒直接用的STL的priority_queue,没办法改变权值,所以都是直接把pair压进堆里。然后时间复杂度O(mlogm),空间复杂度O(m),不靠谱。手写二叉堆?改变权值是O(logn)的,所以时间复杂度O(mlogn),空间复杂度O(n),还是要T。看来是需要一种比较牛逼的堆了。

Fibonacci堆就很牛逼,但是难写难调(算导上都说它“编码复杂度高”、“实践价值不大”、“价值主要在学术方面”。所以我学习了一下它的一个好写好调的替代品:Pairing Heap。它的结构其实就是堆有序的树。下面简单说一下它的几种操作(假定为小根堆)。

  • findMin() 直接返回树根
  • merge(a, b) 把权值较大的挂在权值较小的下面作为子女
  • decreaseKey(a, v) 如果a是根节点,则不改变形态,否则断开a和a的父节点,将两树进行merge
  • deleteMin() 将根节点删掉,然后将子节点从左到右(最左端为最近加入)分对合并,再将合并后的树从右向左合并。
  • delete(a) 执行decreaseKey(a, –oo),然后执行deleteMin()

论文中说除了删除操作为均摊O(logn)的以外其他的都是均摊O(1)(我只弄懂了论文中写的均摊O(sqrt(n))的上界),于是这对于dijkstra优化就有帮助了。因为对每条边都要执行一次decreaseKey,所以decreaseKey从O(logn)优化为O(1)是相当有效的。现在,总复杂度为O(nlogn+m),就可以通过题目了。

BZOJ3040 最短路 (堆优化dijkstra),布布扣,bubuko.com

BZOJ3040 最短路 (堆优化dijkstra)

标签:io   数据   时间   log   学习   简单   优化   on   

原文地址:http://www.cnblogs.com/jasonyu/p/3894077.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!