图论小结

图论小结

1 拓扑排序:复杂度o(n+m)
普通的拓扑排序没什么好说的,在一些特殊结构的拓扑图上(比如自动机,度有限制的图或树),结合最小表示法(我一般都是并查集+map)可以判图的同构

推荐题:Poj3687  Uvalive3981  Ural1872

2 最短路 : 
a) bfs: 复杂度o(n+m),适用于边权为1的图
b) 扩展bfs : 复杂度o(n+m),适用于边权为1或者0的图
算法实现:设一个0~N的桶,桶内装有已知最短路径长度的节点。一开始只有桶0中存有起点S。同时设一个指针p,初始时p指向0号桶。接着分N个阶段扩展,每一个阶段中,依次挑出桶(p-1)中的点扩展 :扩展只用权为1的边;在这之后依次挑出桶p中的点扩展:扩展只用权值为0的边。在执行完这些扩展后,将p加1。由于最短路径长度不会超过N,因此最多扩展到第N个阶段就可以结束算法了。
c) Dijkstra : 复杂度o(n^2+m) 加堆优化后为 o(n+mlogn) 适用于边权非负的图
d) Bellman: 复杂度o(nm) 除了复杂度稍微高了点,几乎是一个完美的算法,好写,无边权要求,可测负环
e) Spfa: 复杂度我也算不出来,有负环的情况下会退化为bellman的复杂度,竞赛时最常用的就是这货…
f) 栈优化的spfa: 复杂度不明,测负环时奇快(如果要写消负环的费用流,非此子莫属了)具体算法实现参照红薯的模板或者2009姜碧野的论文
g) Floyd: 复杂度o(n^3),可动态添边和查询任意点对之间的最短路(或者传递闭包),代码实现出奇地简洁

最短路问题是很多图论问题的基础,如果存在一条边权为w的有向边u->v,则最短路网络上满足dv<=du+w,一般根据这个三角不等式构图即可

推荐题:
Hdu3873 Poj1062 Ural1325 Hdu4096 Poj1275 Poj2949



3 生成树:
a) Prim: 和Dijkstra几乎是一样的,不累述
b) Kruskal: 复杂度o(n+mlogm),要用到并查集,把边按权值排序,依次检查每条边,看两个点是否在同一个联通块里,不是的话就把这条边选了,然后合并两个联通块,代码实现非常简单,我一般都用这个
c) 次小生成树:复杂度o(n^2)这个问题本身没有什么意义,不过其算法实现的思想很值得借鉴,先把最小生成树建好,然后预处理出任意两点之间的最大边权,依次把每条非树边当做一组查询,假设加上这条非树边,要删掉的肯定是对应两个点之间的权值最大的边,然后看看这个边权和增量是多少~
d) 度限制的最小生成树 :个人觉得可以无视,有兴趣的话可以参考汪汀ppt(写得挺清楚的)或者黑书
e) 生成树维护: 动态地加边删边,然后动态地查询一些问题,维护n-1条边,然后每次o(n)地回答查询或者修改操作,总复杂度o(n*q),q为操作数
f) 树形图: 传说那叫刘朱算法?o(n*m)

推荐题:
Poj2421 Poj2728 Poj3522 Hdu4081 ZOJ 3509 Poj 2838 Hdu2121

4 网络流:
这是图论里比较难缠的一块,想得到的时候觉得是水题,否则就觉得是神题…
a) 最大流:建议先把最基本的EK学好,完全理解了再去学sap
技巧:
拆点,在点与点之间的边限制容量,这样可以限制流过某些点的流量
二分参数,然后根据参数构图,再判是否能满流(某些这种题其实动态加边,用EK增广会更快,也更好写...)
最小割构图,定义及构造推荐amber的论文,最大权闭合图推荐2010年林衍凯的论文(暂时见到的讲得最好的~)

b) 费用流:一般直接spfa然后增广都没问题,实在卡得紧的话就每次spfa后多路增广,如果这都TLE的话,那只能说明构图不优越…
强烈推荐《网络流:理论、算法与应用》application里的例题讲解
c) 上下界网络流: 简单二分做法参照周源论文,复杂的不会

推荐题:
Uvalive4259 Uvalive4268 Poj1815 Poj1149 Poj2987 Poj2391 Poj1637 Poj2699 Poj3155 
Hdu3657 Zoj2857 Poj2156 Poj3422 Poj3680 Hdu3947 Hdu4106

5 匹配:
a) 二分图基数匹配:匈牙利算法,我写的复杂度是o(n*(n+m))的,不过一般都跑不满。

如果喜欢敲最大流的话也可以~

相关模型:最小路径覆盖,多重匹配,最小点覆盖

相关优化:

有些二分图其中一边的点数很少,另一边的点数很多,从点数多的一边开始搜匹配方案很可能会TLE,
解决方法是从点集很少的一边去搜

题目给出的图的数据没有分好两个点集,但通过一些条件可以证明这是个二分图,这时候如果去写一个BFS(或者DFS)染色的再跑匈牙利算法的话,代码量略显大了些。
解决方法:不染色直接跑匈牙利,从每个未被匹配的点开始搜增广路,记录方案时要双向记录,整个匈牙利过程的代码基本加一两句代码就够了

b) 二分图最大权匹配:虽然说可以用费用流去写,如果想认真搞ACM的话建议还是把KM搞懂,尤其是其顶标的含义,顺带吐槽一句,我还不明白为啥大家都说km是o(n^3)的,我自己算出来的复杂度是o(n^4),但一般都跑得飞快
推荐资料: http://cuitianyi.com/blog/%E6%B1%82%E6%9C%80%E5%A4%A7%E6%9D%83%E4%BA%8C%E5%88%86%E5%8C%B9%E9%85%8D%E7%9A%84km%E7%AE%97%E6%B3%95/
某些题目,要求du+dv>=wuv(或者du+dv<=wuv),且u和v分属于不同的两个集合(即二分图),求sum(d)的最值,则直接跑km,最后的顶标数字就是一组最优解

c) 一般图基数匹配:有兴趣的话去学学带花树,赛场上我是写不出来这玩意~

d) 一般图加权匹配:参考杨大牛的随机调整算法

推荐题:Poj3041 Poj2289 Hdu3861 Hdu2828 Hdu3729 Uva11985 Poj2195 Poj3686 
Zoj2342 Cdoj1450 Ural1099 Zoj3316 Uvalive4039

6 DFS相关:(这部分是我在图论问题中最喜欢的模块,膜拜tarjan中…)
a) 时间戳:在一个联通块里,DFS树中每个节点进栈和出栈的时间,强连通和双联通问题以及判断某个点是否在某棵子树内都要用到这个,如果把进出时间当做左右括号的话,还能处理很多静态的树上的统计和最值问题
b) Lca:离线的用并查集处理便可,在线的在DFS过程中处理出一个倍增数组(这个还能处理出树链区间上的最值)
c) 树的重心,某些题目利用树的重心的某些性质设计算法会好写很多
d) 有向图强连通分量: Kosaraju和tarjan,注意前者结束后也自动拓扑排好序了
2-sat问题每个点都恰好是两种可能状态中的一种,然后会有一些限制,比如u为状态1的话v就必须为状态0,问是否存在满足条件的解,有时候要求构造出来
具体做法请参考伍煜或者赵爽的论文,如果要构造解的话建议用Kosaraju
e) 双联通分量,割点:注意双联通分量是边集,不是点集…另外,一个桥边也是一个双联通分量~
很多人写的时候是把边压栈的,我个人习惯是给边集开一个并查集,然后直接把属于同一个环上的边合并,这种题常常需要二次构图,第二次构图时把原来的边集和割点当成新图中的点,有关系的连边,然后做一次预处理根据LCA回答相关查询
f) 仙人掌图:点数等于边数的一般都是水题(建议去研究研究cf81e那题watashi的做法),还有一类仙人掌图,每条边最多在一个环内,这种题型的做法是,树形DP,遇到桥则正常转移,否则在时间戳最小的点把环上的信息压到该点上


推荐题:
Hdu3804 Poj3417 Foj1703 Ural1752 Uvalive3713 Hdu4115 Poj2942 Hdu3686 Hdu3896 Uvalive5135 
Spoj Roman Roads  Cf97e Ural1557 Hdu3057 Poj3567 Cdoj1469 Cf81e Srm345 1000 Cf48g sgu487


玩图论的,最好不要做太多模板题,学新算法的时候理解为主,很多看起来不可能在赛场上碰到的算法,有兴趣的话还是建议去学一下,很可能下次遇到一个其他问题但可以用这种算法实现中体现的思想去构思设计新算法~

如果需要看代码的直接登我账号(不要做坏事...)
一般如果在相关OJ找不到的话去HUST看看,少数几题我还没有去写,大部分都应该能找到的
Thost
20023356
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值