图论知识小结
序言——先扯几句闲话
第一次写知识总结,有什么毛病烦请诸位神仙指正(
博客里有些链接来自题目,有些来自我已经写过的博客,如果是博客我就没有再放题解了(懒得搬了~
图论两个重要的问题,一是算法的选择,二是建图。很多算法往往本身有局限性,例如Dijkstra一般不能求含负边的图的最短路,而SPFA一般又不能维护稠密图最短路。
然而图论最重要的不是算法的选择,而是建图。很多人为算法是否可用或者是否好写而常常烦恼,然而建图往往决定了你能拿多少分。
当然两者都很重要,只是近年来的考题都更加注重思维,所以建图变得更为重要。
–最短路–
求解最短路只是一种思想,于我而言,这其实这是在图上DP的过程
最短路的建图关键在于如何利用已知信息构造辅助的边和点,例如我们经常用到的虚点
FLOYD
Floyd复杂度O(N^3),适合求解多源最短路,不过这个算法近来已经不是很常考,有时候会出现倍增Floyd,或者传递闭包
例如奶牛接力这道题,倍增Floyd的板题,利用类似矩阵快速幂的思想,优化到 O ( N 3 ∗ l o g N ) O(N^3*logN) O(N3∗logN)
利用Floyd支持多次查询、修改、删边的图论题也有出现
SPFA
SPFA是一个被Oiers诟病太多了的算法,号称复杂度 O ( k M ) O(kM) O(kM),实际上常常被出题人卡成sb,不过她确实还是好用,例如最短路计数,最短路Dp,最短路+二分,这几类题往往不会以稠密图的方式出现,因此SPFA 有时也能快的飞起
Dijkstra
本身Dijkstra的复杂度其实是 O ( N 2 ) O(N^2) O(N2)的,不过用优先队列或者Set优化可以降低到 O ( N ∗ l o g N ) O(N*logN) O(N∗logN),Dijkstra的效率是有很高程度的保证的,不过也难逃诟病——求含负边权的图的最短路时,显得束手无策,当然在一定限制下也能求,不过就不讨论了。
Dijkstra除了复杂度相对稳定,还有一点就是它相对于SPFA更容易维护字典序,因为优先队列里面存的是一个二元组,第二元在第一元相同的情况下,可以保证编号小的点优先
次短路
这个其实很好办,在最短路的算法里面多维护一个dis2表示次短路即可,板题为Roadblocks
差分约束系统
差分约束系统是基于不等式组而来的一种最短/长路问题,例如给定m个ai-aj的不等式,求a1-an的最大值
建图方式其实已经烂大街了,就是套路:求最大值,所有不等式转为"<=",对于ai-aj<=k,j向i连一条长为k的边,然后跑最短路;求最小值,所有不等式转为">=",对于ai-aj>=k,j向i连一条长为k的边,然后跑最长路
特别地,对于等式,转化成一个"<=",一个">="来连边
虽然说是套路,但放在题目当中还是一道题一个样
几道水题:[SCOI2011]糖果、[SCOI2008]天平、小K的农场
K短路
这种题一般出现在有向图中
主要就是用A* 算法优化,先跑反图求出dis,在以此和到终点的距离为估价函数求前k短路,[SDOI2010]魔法猪学院就是这样一道题
然而A* 算法并没有达到复杂度最优,因为我们只利用了距离这一信息,最优的目前是可持久化可并堆的做法,建议大家看看zxyoi神仙的博客
分层图
分层图其实没什么好讲的,其实本质就是最短路DP,只不过分层图的辅助空间用在加边上了,DP的话直接在Dis数组上加一维,例如可以免费k条边的最短路
一道经典题——逛公园
优化搜索(?)
能够把图论题