![](https://img-blog.csdnimg.cn/20210308203510896.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
AcWing算法提高课
文章平均质量分 82
AcWing算法提高课
打雷要下雨,雷欧
这个作者很懒,什么都没留下…
展开
-
3.7 有向图的强连通分量
连通分量对于一个有向图, 连通分量: 对于分量中任意u, v, 必然可以从u走到v, 也可以从v走到u强(极大)连通分量极大连通分量. 如果连通分量加上任何一个点之后, 都不是连通分量了, 那么称这个连通分量为极大连通分量(强连通分量)强连通分量的用途可以把任意一个有向图, 转化称一个有向无环图.有向图 —>缩点(将所有连通分量缩成一个点)–> 有向无环图(DAG)(拓扑图)有向无环图/拓扑图的好处: 求最短路/最长路的时候, 可以按照顺序递推O(n + m)一般先去求下这个图原创 2021-03-14 17:01:04 · 1001 阅读 · 0 评论 -
3.6 最近公共祖先
最近公共祖先为了一般化, 把一个点本身也称为它的祖先.(将当前点往根节点走, 路过的点全部称为祖先)当然祖先有可能是红色和绿色点中的某一个点, 当然有可能两点是重叠的.向上标记法从一个点开始向上遍历, 在遍历的过程中, 将它路过点的点都标记一下, 比方说搞个bool数组, 路过的全部标记成1.标记完后, 从另外一个点开始往上走, 当另外一个点第1次走到标记的点的时候, 那么当前点就是最近的公共祖先O(n): 最坏情况下一条链, 每次走到根节点倍增法先预处理下, 每个点向上走2k2^k2k步原创 2021-03-12 22:05:43 · 123 阅读 · 0 评论 -
3.5 差分约束
接上节课当我们发现spfa很长时间结束不了的话, 可以近似的认为存在负环上一节课的方式:通过定义int count = 0;然后spfa循环次数超过一个定值, 比如10000if (++ count > 10000) return true; 表示存在负环 / 正环(负环还是正环得根据看spfa求的是最短路还是最长路)这里介绍一个新的方式, 结果上一定是正确的经验上来说, 对于有负环的题目, 效果都会很好.把SPFA中的队列换成栈在SPFA中, 队列只是将等待更新的点, 用容器存原创 2021-03-11 23:00:52 · 111 阅读 · 0 评论 -
3.4 SPFA找负环
负环有向图或者无向图中, 存在环路, 使得一圈的权值之和 < 0, 称为负环负环为什么要单独处理, 比如最短路中, 如果一个点能走到负环上, 那么就能在这个点上转无穷多次, 每转1次, 距离就会小一点, 因此图形中, 某些点的最短路就会变成−∞-\infty−∞, 会影响最短路算法的正确性求负环的常用方法, 基于SPFA(1) : 统计每个点入队的次数, 如果某个点入队n次, 说明存在负环实际上就是bellman-ford算法:bellman-ford算法说迭代n次, 还有点被更新的话,原创 2021-03-08 20:04:32 · 531 阅读 · 0 评论 -
3.3.2 最小生成树的扩展应用
回顾下最小生成树的理论基础解释假设选蓝色箭头的边, 再连上红色边, 因为红色边权 <= 蓝色边, 因此可以去掉蓝色边, 连接红色边, 边权之和会减小解释当前已经有一些连通块, 那么连通块之间的最短边, 一定在生成树里假设连接两个连通块权值最小的边, 左右两个点已经在某个连通块里, 此时如果不选最小的边, 由于这两个了连通块最终会被连通, 被其他路径连通, 因此在其他路径上一定存在边权>= 最小边的边, 因此去掉下面的蓝色边, 加入上面的蓝色边, 边权之和会减小, 不影响连通原创 2021-03-07 15:37:49 · 240 阅读 · 0 评论 -
3.3.1 最小生成树的典型应用
命题: Kruskal算法的正确性证明: 假设不选择“Prim选择的边”, 即选择了红色虚线的边, 那么我们再连接“Prim算法选择的边”, 可以构成环, 然后再删掉红色虚线边, 一定可以使树中权值之和减小, 与当前选择是权值和最小的方案, 矛盾.(因为prim算法计算加边的时候, 保证了选择的边权最小)...原创 2021-03-07 13:03:58 · 4828 阅读 · 1 评论 -
3.2 floyd算法及其扩展应用
总览floyd 原理原创 2021-03-05 14:18:36 · 221 阅读 · 0 评论 -
3.1.3 单源最短路的扩展应用
AcWing 1137. 选择最佳线路分析建立虚拟原点, 做一遍最短路算法codespfa,bfs, dijkstra, A*的判重数组含义的区别spfa中的st数组: 当前元素是否在队列中bfs中的st数组:当前元素是否被遍历过dijkstra中的st数组:当前这个元素有没有出队A*:当前点出队的时候也不能判重,只有终点第一次出队才是最小值, 第k次出队,第k小。...原创 2021-03-04 16:28:33 · 187 阅读 · 1 评论 -
3.1.2 单源最短路的综合应用
这样主要讲解单源最短路和其他算法结合和dfs, 二分, dp, 拓扑排序的结合AcWing 1135. 新年好分析最短路和dfs的结合code#include <iostream>#include <cstring>#include <queue>using namespace std;const int N = 500010, M = 200010, INF = 0x3f3f3f3f;typedef pair<int, int> PI原创 2021-03-04 09:48:27 · 171 阅读 · 1 评论 -
3.1.1 单源最短路的建图方式
单源最短路的一些算法{边权非负{朴素Dijkstra堆优化Dijkstra有负权边{Bellman−Ford(用的情况少)spfa(99%情况用这种算法)\left\{ \begin{matrix}边权非负\left\{\begin{matrix} 朴素Dijkstra \\ 堆优化Dijkstra\end{matrix}\right.\\有负权边\left\{\begin{matrix} Bellman-Ford (用的情况少)\\ spfa (99\%情况用这种算法)原创 2021-02-27 10:35:03 · 224 阅读 · 0 评论 -
2.2.3 DFS之迭代加深、双向DFS、IDA*
#kong原创 2021-02-25 14:32:48 · 246 阅读 · 0 评论 -
2.2.2 DFS之剪枝
常用的剪枝方式原创 2021-02-25 10:53:35 · 152 阅读 · 0 评论 -
2.1.3 BFS中的双向广搜和A-star
AcWing 190. 字串变换注意,扩展节点的时候一定要扩展一层A*证明:A*算法的正确性原创 2021-02-24 11:11:50 · 255 阅读 · 0 评论 -
2.2.1 DFS中的连通性和搜索顺序
DFS第一大类可以解决的问题BFS/DFS⇒{Flood Fill模型图与树的遍历BFS/ DFS\Rightarrow \left\{\begin{matrix} Flood\ Fill 模型\\ 图与树的遍历\end{matrix}\right.BFS/DFS⇒{Flood Fill模型图与树的遍历此类问题,一般是判断树与图的内部,是否连通DFS第二类问题搜索顺序,剪枝与优化,迭代加深, IDA*, 双向BFS。这些问题基本是把整个问题看成是一个整体,问我们原创 2021-02-25 08:22:33 · 193 阅读 · 0 评论 -
第二章搜索 题目总目录
2.2.1 DFS中的连通性和搜索顺序DFS之连通性模型AcWing 1112. 迷宫AcWing 1113. 红与黑DFS之搜索顺序AcWing 1116. 马走日AcWing 1117. 单词接龙AcWing 1118. 分成互质组原创 2021-02-25 12:51:12 · 111 阅读 · 0 评论 -
1.2.2 最长上升子序列模型(二)
1010. 拦截导弹分析就是最长不上升子序列再加一问,最少需要几套系统才能拦截所有导弹?贪心:从前往后扫描每个数,对于每个数:情况1:如果现有子序列结尾都小于当前数,则创建新的子序列情况2:将当前数放在结尾大于等于它的最小的子序列后面。code(第二问贪心)#include <iostream>using namespace std;const int N = 1010;int a[N], f[N], n, g[N];int main(){ while (c原创 2021-03-27 23:04:49 · 66 阅读 · 0 评论 -
1.2.1 最长上升子序列模型(一)
例题:怪盗基德的滑翔翼分析1.随意选个楼顶作为起点。2.随意选个方向,选定方向就固定了。这两点确定了之后,假定以 a[i] 为起点,则最长距离就是以 a[i] 为结尾的最长上升子序列。在两个方向上(左到右,右到左)各求一次最长上升子序列即可。code#include <iostream>#include <cstring>using namespace std;const int N = 110;int a[N], f[N];int n;int main()原创 2021-03-07 18:56:49 · 142 阅读 · 0 评论 -
1.1 数字三角形模型
AcWing 1015. 摘花生分析code#include <iostream>#include <cstring>using namespace std;const int N = 110;int f[N][N], w[N][N];int n, m;int main(){ int T; cin >> T; while (T -- ){ memset(f, 0, sizeof f); cin原创 2021-03-06 14:19:53 · 120 阅读 · 0 评论