ACM暑假集训第三周小结

这一周学的图论,学了这么些

两种存图的方法:邻接矩阵( map[n][n] ) , 邻接表( headlis[n] , vector<int> G[n] )
存图的方法,各有各的好,我的理解是,如果不是那种非常稠密的图,类似于完全图这样的图,邻接表一般会快很多,毕竟减少了边的遍历。

最小生成树 kruskal
这个算法现在感觉是到的用处是,求将所有点连通起来,并且边的权值之和最小的一种算法,
首先,将边按边的权值升序排序,每次选取最小的边,如果没有连通,就连通起来,并记录权值,用一个并查集确定两点是否连通,
并查集确定是否连通很容易实现,并查集的压缩路径也很简单。这个算法感觉有点贪心的意思。

最短路径 dijkstra , bellman-ford ,floyd ,spfa
dijkstra
适用于边权为正的情况,有向图,无向图都适用
这个算法就是走一步看一步的意思,选最短的路径走一步,然后去看去所有点是否能经过这个点能更短路径。
d[]这个数组的意思一定要确立好,例如找最短路径就是记录到这个点最短的距离,最短时间就是存到某个点的最短时间

先初始化,d[n]都设为 inf , vis[] 都设为0 , 然后起点s,d[s]=0,遍历 n 次,每次找到最小的距离去没经过的点,然后标记走到了,然后去更新这个点到其余没到过的点是否能缩短
路径,这样,标记 n 次,也就是说所有点都走到了咯,能更新的都更新完了。

优化方法:用邻接表存,可以减少遍历,然后 d[] 换成一个优先队列,小的先出队,这样就代替了循环 n 次找最小的权值了,

bellman-ford
能做有负权的
算法我用的比较少,不是十分理解,欢迎指正。
我的理解是循环 n-1 次, 每次检查每条边,如果起点可以到,去松弛这条边连的两个点,不知道为什么需要 n-1 次能松弛完。。。

floyd

感觉这个更暴力,直接三重循环遍历点数 n ,k 循环 n 次,就是看经过 k 这个点是否能够缩短权值,能就缩短
使用先估计会不会超时吧。初始化就是除了读入边之外,将 d[i][i]=0

spfa
网上看的一个算法,一般比 dijkstra 要慢一点
我最喜欢的,感觉像是bellman-ford 的优化,又感觉有点bfs的意思,很有趣
就是从起点开始走,遍历这个点能去的所有边,然后看能不能优化,能优化,就去试探被优化的那个点的所有边,看鞥不能继续优化,如此深入
直到不能优化了,就会退出,然后就是一个完全优化的数组 d[] 在你的面前,哈哈哈

网络流初步 增广路算法
看那本《算法竞赛-入门经典》写的很简洁,看了很久没看懂,百度一下,so easy ,哈哈,一下子看懂了最大流问题,估计最近没时间看后面的了
以后写总结

原文地址:https://www.cnblogs.com/haoabcd2010/p/5723610.html