Codeforces Round #406 (Div. 2)

https://codeforces.com/contest/787/

D - Legacy

题意:有一个n(<=1e5)个节点的图,有q组边,t是目的地。每组边有3种type之一:
t1:u v w (u到v有w的单向边)
t2:u l r w (u到[l,r]有w的单向边)
t3:v l r w ([l,r]到v有w的单向边)
求从第i个节点到t的最短路。

题解:
失败的想法:新增一个节点管理所有的[l,r],这样避免不了对边的遍历。使用链表删除节点来加速对t2区间的操作,但是对t3的无能为力,而且这个t2也很好卡,每次只有dijkstra真正vis的时候才能删除,所以还是n^2的算法。
正解:先把所有的边反向,目的地t变成起始点s。对连续区间的操作,考虑用线段树来优化,假如只是用线段树求两点之间的距离的最小值,空间会存不下,边也会太多。真正的做法是按线段树来给节点分组,叶节点表示原图这个节点本身,内部节点表示其之下的所有叶节点,每个内部节点向其儿子连w为0的有向边。t2的操作使得u连上log(r-l+1)个内部节点,t3的操作使得log(r-l+1)连上v。然后对这4n个点跑一次dijkstra找到对每个节点的最短路。这个算法的优化在于把[l,r]条边分解为log(r-l+1)条,然后根据线段树的结构重用了大量权为0的边,是对失败的想法的正确实现,失败的想法1的失败原因是没有办法减少边的数量,而假如有规则地断成一系列点的话,可以重用大量的边。

标签:数据结构:线段树、图论:最短路

posted @ 2019-12-09 23:03  KisekiPurin2019  阅读(125)  评论(0编辑  收藏  举报