前言
最近一直在刷联赛题目,遇到了很多无向图上的问题,就在此总结一下。
进入正题
第一类
就是一个无向图上,跑某两个点最短路,然后有些使用次数比较小的绕路方法(某些点连出去的边费用减免,抄捷径之类的)。
一个比较好的思想就是分层,每层跑一次最短路,从上层转移,spfa+slf的算法一般卡不掉(这算比较快的)。
还有些一次性连边跑最短路的要尽量避免(时间特别慢),会走到许多冗余的状态。
第二类
无向图上找一些权值平均值最大(或最小的环)。
这种总权除以数量的很经典是二分,然后就是判断负环(正环)问题。
这里可以用bfs版spfa+slf,判断一个点入队是否超过n次。
dfs的spfa一般情况下更快。
第三类
就是给出很多加边(或删边)操作,支持中途查询的问题。
首先一般都需要并查集,然后如果删边就时光倒流一下,维护些数据结构之类的。
现在说一类十分相似的问题。
给出一个无向图,然后加边,要维护一些最大权最小的问题,支持查询。
代表题目:
【NOI2014】魔法森林
等
通常就是排序,维护最小生成树上两点的最大值,把两点之间最大值修改。
用一道题题解结束吧。
【JZOJ4731】游戏
首先关于策略,如果两堆石子相同,先手必输,否则先手必赢。
证明:如果两堆石子相同,先手在某一堆取走多少石子,后手都可以在另一对中取走相同数量的石子,所以除非先手取完一堆中所有的石子,否则两堆都有石子。但此时后手可以把另一堆取完,所以后手必胜。
如果不同,那么先手可以把两堆石子取成相同的,那么此时的后手就是前面情况的先手,所以先手必胜。
然后,这题的一条路径的权值为这条路径包含边的边权最大值,两点之间路径为所有路径权值最小值,那么可以动态维护一个最小生成树。
具体操作:
加边时如果不形成环,那么直接加入,否则找到环上权值最大的边视情况替换掉。
查询就是树上两点路径最大值。
这可以用LCT维护,因为这题数据比较小,所以暴力维护也可以过。
隐形分割线
第三类问题思路不难,但代码一般有些长(并查集+数据结构维护最小生成树)。
总结
也没什么好说的了。
就这样结束吧。