【总结】图论 · 知识点

最短路:

1.spfa:

/从原点开始,每次找相邻的点入队,更新它的最短路 
注意:要初始化:nxt,head(first),dist,vis
至于为什么进队两次:因为有些点左右都有邻点,可能会被邻点更新两次,所以入队次数<=2
//(自己的理解)
而且每次更新完dist点入队后又以它开始spfa更新邻点,所以一定会出队一次 

/适用范围:无负环但可以有负边的有向图, 不带负边的无向图/

+SLF优化

使用双端队列,每次更新完dist与队列中现在的front比较,若与front相比离源点近则放在队头, 
否则放在队尾 

判负环

"(1)BFS: "依然为spfa的过程,只不过在原有算法的基础之上 在更新完dist有新的点要入队时, 
累加它的进队次数,若超过n次,则存在负环 :O(ke) k为进队次数,如果有负环的话进队>n次, 
那这个时间复杂度就会很大

 "(2)DFS: "初始化与BFS时不同,我们把dist数组初始化为0,那么能更新最短路的只能是负边,所以 
遇到能更新的就记录一下这个边的点,看其是否又被更新即可,若有负环,则负环上的点的最短路一定会 
被不断更新,绕一圈小一点,毕竟存在负边 :O(nlogn) 

2.dijkstra:

找与当前点相连的点中离起点最近的点(一个for)来继续更新其它与它相邻的点(又一个formin:记录当前与起点最近的点 到起点的距离 

推荐http://www.codeweblog.com/通俗地告诉你-为什么dijkstra算法是正确的/
(以下有引用内容)

(最小堆ugly_num问题做法正确性:lastoutput(以下简称ltp)实际上一直再重复两个操作:
第一次:记录当前最小值,同时把它的“儿子”放到堆里,第二次,通过ltp=最小值 把最小值输出出来,
然后与下一个堆顶比较,此时ltp 的值还停留在上一个最小值的值,所以把它更新为当前的最小值,
同时把它的“儿子”放到堆里,再进行第二次操作,把它输出来以此类推 
由于某个数的儿子是它*2/*3/*5,所以一定比它大,不会撼动它当前的最小值地位 

//(以下为自己观点:如果我们考虑直接暴力求解的话,for一遍看哪个可以被2/3/5整除即可,但是被610等 
这些数正除也是可以的,因为它们是2,3,5的倍数,所以这样的话ugly_num的判断就很模糊,难不成要求出
2,3,5的所有倍数?forfor是n方的显然如果数据较大,一定会超时,但是实际上,我们需要输出k次每次 
就只是要找最小的,能使我们每次都能找到最小的就可以用最小堆(stl里的优先队列虽然是最大堆但是也可以 
我们只要把每个数*(-1)压入队中,取出时在*(-1)把它还原回来就好啦),它可以保证堆顶永远是最小的 
干好符合我们的要求,然后利用上述操作即可,感觉好机智的方法) 
"总结:当前最小的num是由之前最小的派生出来的--->当前的最短路是由之前的最短路派生过来的 
(min更新min)(突然想到了lca中的low值更新low值#@¥#@%……*&……*……)"
那考虑为什么不能有负环呢?因为当前的最短路会被无限次的更新,就不会有最短路这一说, 
最短能短到什么程度我们也不清楚,﹣无穷吗?

【其实想一想,spfa不能处理带负边的无向图也是这个原因,有负边,还无向,那负边端点就
可以一直更新zdl,它既然可以更新,就会无限次的入队来更新邻点,邻点的最短路以及后面的点的最短路
就一直无法确定,那也就不会知道所谓的最短路是谁了,只要一直走负边,路就会变得更短 】)

  1. 图不包含负数权值的边 => 这个条件告诉我们: 一个长的最短路径肯定是由一个比它短的最短路径派生
    出来的。也就是说,最短路径的发现过程可以存在单调性,先发现短的,
    然后利用短的来发现长的。又或者说,如果两个最短路径具有派生关系的话,我们就认为有一条边
    从“父亲”指向“儿子”。按照长度对最短路径序列排序后,我们会看到,所有的边都是从左指向右的
    (类似于拓扑排序后的效果),所以我们可以先算左边的,然后算右边的。
    这个技巧,其实就是动态规划里的那一套!
    **说到DP,其实无论是图的最短路径还是DP,归根到底,都是“具有最优子结构”的问题,这一类问题,
    其实就是计算若干个最优解,而计算它们的策略,是可以有很多种的,千万不要绑住自己的想象力,
    只要能正确地算出来,用什么方法都ok。

3.Floyd:

3for循环,求多源最短路,枚举中间点k,利用中间点更新zdl,考虑到间接路可能更近 
注意for的顺序,k一定在第1层,保证所每个中间点都考虑过,都能参与任意两个点最短路的更新过程 
(对zdl有没有贡献就不一定了)  

最小生成树:

Kruskal:通过并查集实现:每次取边权最小的边,若两端点的fa不一样则加入生成树中,若是fa一样了还加,
而这条边还没有访问过,那这两点之间就会出现两条不一样的路径,就形成了环 :O(|E|log|V|)

推荐http://www.cnblogs.com/tahitian-fang/p/5751298.html

堆优化:木有做过qwq

Prim:木有做过QAQ


拓扑排序:

记录每一个点的入度(输入时),每次选取入度为0的点,将它输出并且把与它相连的点的入度-1
重复上述操作


并查集:

不再多说,遇到分伙问题想想并查集,别想得太复杂

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值