最短路,前缀和优化连边,Dijkstra(UESTC 482,Charitable Exchange)

http://acm.uestc.edu.cn/#/problem/show/482


做了这道题目很有收获,一方面是熟练了优化连边的技巧,另一方面是对Dijkstra有了新的感悟。


关于优化连边的做法:

首先离散化,将1e9范围的数离散化,重新分配编号,这样最多有2e5个节点。

很显然,题目中的边是一种区间到单点的边,所以可以考虑线段树优化连边,可能是因为自己不够熟练,实现得不好,所以超内存了,但是看到有人这样做过了的。

但是有更好的优化方式,可以有更小常数的时空复杂度。

我们发现起点区间有一个性质,那就是右边界一定在最右边,一共有n个区间,所以就不用线段树优化了,可以后缀和优化,每个区间新建一个节点,直接区间到单点连边,然后每个区间和前面的区间连边,跑Dijkstra就好了。


关于对Dijkstra的新感悟:

主要是看了这篇博客的解法,在思考为什么正确的过程中对Dijkstra有了更深的认识。

http://blog.csdn.net/xinag578/article/details/50883997

博主说是广搜+优先队列优化,其实本质上就是Dijkstra的O(nlogn)优化啦。

n条边各用一次,因此最多产生n个新节点,放入优先队列中,时间复杂度O(nlogn)。

我一直疑惑为什么要挑一个t最小的点,然后把所有能用的边都用了,就可以得到正解。主要是疑惑为什么敢这么大胆地把用过的边都丢掉,难道保证这样做物尽其用了吗?

通过和Dijkstra的对比后发现,它们的做法其实没有任何区别,Dijkstra也是挑一个d最小的HeapNode,然后把所有从这个Node出发的边都用掉,更新其他节点。

由于每个节点只done一次,所以每条边只用一次,一共e条边,产生的新节点个数其实不太好估计,会有重复。仔细想了想最优是O(n)最差是O(n^2),但是那不重要,因为要取对数,平方就变成常数了,因此时间复杂度为O(elogn)。


下面讲一讲为什么敢这么大胆地把用过的边丢掉,即证明物尽其用了。

首先,边的作用就是为了更新节点,如果能保证这条边更新的情况是最完美的,那就必然物尽其用了。

何时才最完美呢?一条边的终端是固定的,边的长度也是固定的,那么只有当边的起始端的d是最小的时候,更新就是最完美的。

Dijkstra算法每次挑出d最小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值