![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
图论
文章平均质量分 68
介绍算法之一——图论
爱寂寞的时光
这个作者很懒,什么都没留下…
展开
-
图论——多源最短路Flody-Warshall算法
图论——多源最短路Flody-Warshall算法Flody-Warshall算法在本文中,我们使用一种不同的动态规划公式来解决所有节点对的最短路算法。称为Flody-Warshall算法。其运行时间为O(V3)O(V^3)O(V3)。Flody-Warshall算法考虑的是某一条最短路上的中间节点。设图GGG的节点集合为V={1,2,…,n}V=\{1,2,\ldots,n\}V={1,2,…,n},令VVV的一个子集Vk={1,2,…,k},k≤nV^k=\{1,2,\ldots,k\},k \原创 2021-11-05 20:57:17 · 154 阅读 · 0 评论 -
图论——最大匹配
图论——最大匹配匹配:定义一个图G=(E,V)G = (E,V)G=(E,V) ,匹配是指边集的一个子集V′⊆VV' \subseteq VV′⊆V。在V′V'V′中,没有任意一个节点uuu,使得uuu与aaa边相连又与bbb边相连(a≠ba \neq ba=b)。极大匹配:在一个匹配MMM中,再也不能添加一个边aaa使得M∪{a}M \cup \{a\}M∪{a}也是一个GGG的匹配。最大匹配:在所有极大匹配中,边集数量最大的那个就是最大匹配,最大匹配可能不唯一。树的最大匹配P1623原创 2021-10-19 02:03:31 · 5078 阅读 · 0 评论 -
图论——k短路
图论——k短路P4467A*算法定义一个A*算法f(x)=g(x)+h(x)f(x) = g(x) + h(x)f(x)=g(x)+h(x),定义为g(x)g(x)g(x)为从aaa到xxx的走过的路径长度,h(x)h(x)h(x)是反向图中δ(x,b)\delta(x,b)δ(x,b)。那么第kkk次访问bbb的时候就是kkk短路。注意对字典序的排序。struct Edge{ int to; int nxt; ll wi;};struct Graph{原创 2021-10-18 12:19:38 · 290 阅读 · 0 评论 -
动态规划——Rerooting DP
动态规划——Rerooting DPRerooting DP 方法是解决一类树上DP问题的一般解决方法,与树形DP不同的是,树形DP只根据节点的儿子节点计算得到父节点的答案,而在Rerooting DP法中,将每个节点都看成是该颗树的根节点,根节点在树中转移,因此叫Rerooting DP方法。原文地址(日文):Rerooting DPRerooting DP包括两次DFS:计算子树答案(树形DP)。根节点转移。本文将以ABC222 F为例子,讲解Rerooting DP。子树答案定义原创 2021-10-13 20:45:32 · 252 阅读 · 0 评论 -
树上欧拉序列
树上欧拉序列树上欧拉序列表示根节点走,按照DFS的方式遍历整颗树,并且把路径上沿途的所有节点都记录下来(包括返回),组成的节点数组称为欧拉序列。欧拉序列满足任意两个连续的节点,其中都存在一条边连接两个节点。欧拉序列求LCAO(nlogn)O(n \log n)O(nlogn)时间预处理,O(1)O(1)O(1)时间查询。我们定义DSF访问序列:每一次进入节点和退出节点均需要记录:序号节点ID深度1xxxx2xxxx则我们查询LCA是在表中两个节点ID之原创 2021-10-04 11:24:39 · 1021 阅读 · 0 评论 -
图论——次小生成树
图论——次小生成树我们定义一个图的次小生成树(如果存在)为边权之和大于等于最小生成树的第二小生成树。由于次小生成树和最小生成树之间只差一个边的改动,我们可以先求一边最小生成树,遍历所有未添加的边(u,v)(u,v)(u,v),并计算路径u→vu \to vu→v中的最大边权,用这个边去替换最大边。在所有方案中取最小即可。这样求的生成树是不严格次小生成树,如果要求严格次小生成树,我们必须维护路径上最大和次大边权,在所有方案中取最小即可。可以通过树链剖分,倍增,ST表实现。P4180#include原创 2021-08-15 22:12:39 · 217 阅读 · 0 评论 -
矩阵树定理
矩阵树定理矩阵树定理也称Matrix-Tree定理或Kirchhoff定理。这个定理提供了一种方式使用一个特殊的矩阵的行列式来计算一个图的生成树的数量。对于一个无向图来说,我们可以构造它的Laplace矩阵LLL,其中:如果节点iii有度为ddd,那么L[i,i]=dL[i,i] = dL[i,i]=d如果节点iii和节点jjj之间有边相连,那么L[i,j]=L[j,i]=−1L[i,j] = L[j,i] =-1L[i,j]=L[j,i]=−1其他情况L[i,j]=0L[i,j] = 0L[i原创 2021-08-06 12:53:34 · 1443 阅读 · 0 评论 -
树哈希(Tree Hash)
树哈希(Tree Hash)顾名思义,对树进行哈希,经常判断两个树是否同构。一下均为对有根树的算法,而无根树只需要找重心无权树方法一fnow=sizenow×∑fson(now,i)×seedi−1 f_{now}=size_{now} \times \sum f_{son(now,i)}\times seed^{i-1} fnow=sizenow×∑fson(now,i)×seedi−1其中 fxf_xfx 为以节点 xxx 为根的子树对应的哈希值。特殊地,我们令叶子节点的哈希值为 11原创 2021-07-26 16:01:50 · 4209 阅读 · 0 评论 -
2-SAT适定性问题与逻辑图
2-SAT适定性问题与逻辑图逻辑图逻辑图是一种有向图,图中每一个节点代表了一个命题,如果命题aaa是命题bbb的充分不必要条件,那么在aaa和bbb之间就存在一条有向边a→ba \to ba→b。如果aaa和bbb互为充要条件,那么aaa和bbb之间存在双向边。构建逻辑图可以为我们通过图论解决命题之间的关系等问题,例如2-SAT问题。2-SAT适定性问题SAT 是适定性(Satisfiability)问题的简称。一般形式为 k - 适定性问题,简称 k-SAT。而当 k>2k > 2原创 2021-07-15 11:35:11 · 425 阅读 · 2 评论 -
树查询算法
树上差分思想是将树看成是相交线段进行差分。分为点差分和边差分。通常需要结合LCA来实现。其实更推荐树链剖分,树链剖分可以很好的把LCA和线性结构组合在一起。点差分以统计一条路径上经过的点的次数为例子。我们定义节点xxx的差分变量:diffx=valx−∑s∈sonxvals\text{diff}_x = \text{val}_x - \sum_{s \in \text{son}_x} \text{val}_sdiffx=valx−s∈sonx∑vals我们有路径δ(s,t)\del原创 2021-07-05 15:08:51 · 455 阅读 · 0 评论 -
DAG的覆盖与转换SCC问题
DAG的覆盖与转换SCC问题给定一个有向无环图GGG,请问:选择最少的节点数AAA,可以遍历整个图GGG。添加最少的边BBB,使得整个图变成一个强连图分量。问题1考虑拓扑排序,根据贪心的思想,我们从入度为000的节点开始选择,因此答案就是入度为000的点的个数。问题2考虑贪心,每次我们都选择一个最大的路径,将其首尾连接,变成一个环,使得一个入度为000(起点),出度为000(终点),加入到强连通分量中。直到变成一个强连通分量(出入度为000的点只有一个)为止。因此,答案就是出度为000的点原创 2021-04-10 23:27:20 · 209 阅读 · 0 评论 -
图上倍增
图上倍增在一个有向图、无向图上进行倍增。一般设数组G[i][j][k]G[i][j][k]G[i][j][k],表示是否有从i→ji \to ji→j的路径,且路径的长度为2k2^k2k.更新方法:最外层枚举kkk,内层枚举点对i,ji,ji,j,最内层枚举中间点ttt,使得G[i][j][k]=G[i][t][k−1]ANDG[t][j][k−1]G[i][j][k] = G[i][t][k-1] AND G[t][j][k-1]G[i][j][k]=G[i][t][k−1]ANDG[t][j][k原创 2021-04-08 21:15:56 · 156 阅读 · 0 评论 -
树的重心和中心
树的重心定义树上的每一个节点都有一个平衡值,该平衡值的定义为,以该节点为根节点,所有子树中节点数量最大的那个子树中节点数量。树的重心是树上的一个节点,其平衡值是树中节点中最小的那个。性质以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条原创 2021-04-05 00:09:36 · 1458 阅读 · 0 评论 -
图论——二分图最大匹配与匈牙利算法
匈牙利算法二分图概念二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。准确地说:把一个图的顶点划分为两个不相交集UUU和VVV,使得每一条边都分别连接UUU、VVV中的顶点。如果存在这样的划分,则此图为一个二分图。二分图的一个等价定义是:不含有「含奇数条边的环」的图。判断一个图是不是二分图,我们可以使用BFS搜索算法,从一个顶点开始搜索整个图,层与层直接交替出现,即二分图的左点集和右点集交替出现,该图是二分图的充分必要条件是,BFS搜索中不出现横向边。等价原创 2021-03-19 20:08:06 · 471 阅读 · 1 评论 -
欧拉回路——Hierholzer算法
欧拉回路——Hierholzer算法对于一个欧拉回路,我们分析其组成部分,一个欧拉回路必是由多个环连接在一起,才能符合所有的点入度与出度相等。因此Hierholzer算法算法的核心就是依次寻找环,将所有的环拼合成一条欧拉回路。过程首先我的定义一个双端链表和一个队列,设链表为TTT就是最后的欧拉回路的路径,队列BBB类似于BFSBFSBFS算法中的队列的作用。队列中的元素是一个二元组(v,Tv)(v,T_{v})(v,Tv),其中vvv是图中节点的编号,TvT_{v}Tv是这个节点在链表TTT的原创 2021-03-16 00:09:26 · 1681 阅读 · 0 评论 -
并查集与二分图染色法
并查集与二分图染色法原理:把相同颜色的放进一个联通集合里面,建立一个数组,记录与根不相同的节点。具体请看代码:P1525#include <bits/stdc++.h>using namespace std;#define FR freopen("in.txt","r",stdin)#define FW freopen("out1.txt","w",stdout)typedef long long ll;struct pp{ int from; int原创 2021-02-27 14:37:12 · 168 阅读 · 0 评论 -
图论——最小环
图论——最小环对于一个有向图或一个无向图,如何求它的最小环的大小呢,默认边的权都是1。Floyd算法求最小环(性能差)设节点iii和jjj为遍历节点kkk为中点,那么当i=ji=ji=j的时候,如果存在i→ki \to ki→k和k→jk \to jk→j,那么就会存在环i→k→j(i)i \to k \to j(i)i→k→j(i)此时最短路就是环的大小。#include <bits/stdc++.h>using namespace std;#define FR freopen原创 2021-02-26 22:25:04 · 503 阅读 · 0 评论 -
Tarjan连通算法
Tarjan强连通算法Tarjan 算法是基于深度优先搜索的算法,用于求解图的连通性问题。Tarjan 算法可以在线性时间内求出无向图的割点与桥,进一步地可以求解无向图的双连通分量;同时,也可以求解有向图的强连通分量、必经点与必经边。如果你对上面的一些术语不是很了解,没关系,我们只要知道 Tarjan 算法是基于深度优先搜索的,用于求解图的连通性问题的算法 就好了。提到 Tarjan,不得不提的就是算法的作者 ——Robert Tarjan。他是一名著名的计算机科学家,我们耳熟能详的 最近公共祖先(L原创 2021-02-19 13:35:13 · 217 阅读 · 0 评论 -
图论-最大二分匹配
图论-最大二分匹配最大二分匹配问题给定一个无向图G=(V,E)G=(V,E)G=(V,E),一个匹配是边的一个子集M⊆EM \subseteq EM⊆E,使得对于所有节点v∈Vv \in Vv∈V,子集MMM中最多有一条边与节点vvv相连。如果子集MMM中的某条边与节点vvv相连,则称节点vvv由节点MMM所匹配。否则,节点vvv就是没有匹配的。最大匹配是最大基数匹配,即对于任意匹配M′M'M′,最大匹配∣M∣≥∣M′∣|M| \geq |M'|∣M∣≥∣M′∣。这个匹配MMM被称为最大匹配。\二分图原创 2021-02-05 11:02:20 · 316 阅读 · 0 评论 -
最大流-Ford-Fulkerson方法
最大流-Ford-Fulkerson方法基本Ford-Fulkerson算法Ford-Fulkerson方法的基本思想是,在每次迭代中,先在残存网络中寻找一个增广路径,然后将流按照增广路径增加即可,直到找不到增广路径为止。伪代码可以写出:FORD-FULKERSON(G,s,t) for each edge(u,v) in G.E (u,v).f = 0 while Gf.p is not null cf(p) = min(cf(u,v) : (u,v) in p) for each原创 2021-02-04 23:12:53 · 878 阅读 · 0 评论 -
流网络初步
流网络初步此文,我们来到了图论里面最重要的专题——流网络。此文正如标题所说,介绍一些流网络中常见的概念和定理。流网络和流流网络是一个有向图G=(V,E)G=(V,E)G=(V,E),图中每一条边都有一个非负的容量值c(u,v)≥0c(u,v) \geq 0c(u,v)≥0。而且,如果边集合包含一条边(u,v)(u,v)(u,v),就不会存在反向边(v,u)(v,u)(v,u)。为了方便起见,如果(u,v)∉E(u,v) \notin E(u,v)∈/E,那么c(u,v)=0c(u,v) = 0c(原创 2021-02-04 11:15:46 · 519 阅读 · 0 评论 -
差分约束系统
差分约束系统线性规划在通用线性规划问题中,我们通常给定一个矩阵AAA,和一个未知向量→x\underset{x}{\rightarrow}x→,和一个已知向量→b\underset{b}{\rightarrow}b→。求解矩阵不等式Ax≤bAx \leq bAx≤b。有时候我们并不关心目标函数,而是希望计算出一个可行解(或告知无解)。差分约束系统在一个差分约束系统中,线性规划矩阵AAA每一个都有且仅有一个1和-1,其他位置均为0。因此,由Ax≤bAx \leq bAx≤b所给出的差分约束系统是由原创 2021-02-03 10:37:23 · 77 阅读 · 0 评论 -
BellmanFord算法、多源最短路与矩阵相乘
BellmanFord算法、多源最短路与矩阵相乘BellmanFord算法与动态规划相信看到这篇的读者已经对BellmanFord算法有了详细的认识。在这里我就不再赘述了,直接讨论与动态规划的关系。我们定义lxml_{x}^{m}lxm为从源节点到节点x且最多经过m条边的最短路径的距离,为了构建动态规划的状态转移方程,我们必须分析lxm−1l_{x}^{m-1}lxm−1与lxml_{x}^{m}lxm的关系。为了从lxm−1l_{x}^{m-1}lxm−1递推到lxml_{x}^{m}lx原创 2021-02-01 23:06:37 · 285 阅读 · 0 评论 -
图论-最大、小高度树
图论-最大、小高度树问题Leetcode 310分析用树的直径证明BFS答案要么是一个节点,要么是两个节点首先我们证明一下答案要么是一个节点,要么是两个节点。我们先给出树的直径的定义:图中所有最短路径的最大值即为「直径」,可以用两次 DFS 或者树形 DP 的方法在 O(n) 时间求出树的直径。我们把一个树的直径拉成一条直线:图中橙色节点为树直径上的节点,蓝色节点代表其他与图连通的其他节点。我们给出以下断言:最小高度树的节点只能是树直径上的节点,而且必须是直径的中点。我们设树原创 2021-01-29 22:43:10 · 775 阅读 · 1 评论 -
图论-最小生成森林
图论-最小生成森林问题P1195分析通过连接一些边,将这些节点连成k个最小生成树,构成的最小生成森林。我们有一下推断:含有一颗最小生成树,需要连接n-1条边,含有两颗最小生成树,需要连接n-2条边,含有k颗最小生成树,需要连接n-k条边。因此,我们只需要连接n-k个边即可,使用Kruskal算法即可。如果没连到n-k条边优先队列就为空了,那么就是无解。代码#include <bits/stdc++.h>using namespace std;int pre[1005];原创 2021-01-28 22:35:44 · 1684 阅读 · 0 评论 -
图论-欧拉图
图论-n笔画和欧拉图问题P1636分析对于一个无向连通图,求用几笔能画完?每一次起笔都从度为奇数的节点开始画起,画到任意另一个度为奇数的点结束,去掉已经画完的边,这个图将可能被分成几个连通分量,但是奇数度的点的个数不会变,每画一次就会消掉一对奇数点,因此答案为奇数度点的个数除以2。对于欧拉图我们要特判一下,如果是欧拉图答案应该是1而不是0。对于非连通图,我们应该通过dfs或者bfs用这个方法求每一个连通分量的笔画数,之后相加即可。...原创 2021-01-28 19:13:07 · 1603 阅读 · 0 评论 -
图论-DAG图中的最短路问题
图论-DAG图中的最短路问题根据节点的拓扑排序的次序来对带权重的有向无环图进行边的松弛操作,我们便可以在Θ(V+E)\Theta(V+E)Θ(V+E)的时间内计算出从单个源节点到所有节点之间的最短路径。因为DAG无环,因此不存在负权环,因此源节点到任意的最短路都是存在的。我们只需要按照拓扑排序的次序,来依次松弛节点的邻接边,即可。证明对于任意s到v的最短路(v0,v1,…,vk)(v_{0},v_{1},\dots,v_{k})(v0,v1,…,vk),v0=s,vk=vv_{0}=s,v_{原创 2021-01-28 14:10:34 · 434 阅读 · 0 评论 -
图论-SPFA
图论-SPFA就像在我上一篇文章中提到的那样,BellmanFord算法有很多不必要的松弛操作,对于某一个最短路来说(v0,v1,…,vk)(v_{0},v_{1},\dots,v_{k})(v0,v1,…,vk),从v0v_{0}v0所连的边开始松弛才是最高效的,因此我们有如下定理:只有那些刚被松弛的边所连接的节点,才会引起这个节点所连的边松弛。我们根据这一条定理,给出了BellmanFord算法的改进算法,即SPFA(Shortest Path Faster Algorithm)。voi原创 2021-01-28 11:47:38 · 76 阅读 · 0 评论 -
图论-BellmanFord算法
图论-BellmanFord算法BellmanFord算法用于计算单源多节点最短路问题,并且能够处理负权重的边和判断是否存在负环。松弛操作在计算每个节点v来说,我们维持一个属性v.d为源节点s到v节点最短距离的上限。称为s到v的最短路径估计,松弛操作就是减少每个节点的v.d值,也就是最短路径的上限。void relax(int u, int v, int w){ if (d[v] > d[u] + w) { d[v] = d[u] + w; }}原创 2021-01-28 11:11:11 · 168 阅读 · 1 评论 -
图论-强连通分量
图论-强连通分量Kosaraju 算法我们定义节点的f值,即v.f为在DFS中节点的完成时间。我们有这样的事实:如果在有向图中,如果存在u→vu \to vu→v,那么u.f>v.fu.f > v.fu.f>v.f一定成立;反过来,如果存在v→uv \to uv→u,那么u.f<v.fu.f < v.fu.f<v.f一定成立。之后,我们用一个强连通分量中节点最大的f值代表这个强连通分量的f值。那么有如下的事实成立:如果在分量图GSCC=(VSCC,ESCC)G原创 2021-01-26 20:34:31 · 174 阅读 · 0 评论 -
图论-树的直径
图论-树的直径问题我们将一颗树T=(V,E)T=(V,E)T=(V,E)的直径定义为maxu,v∈Vδ(u,v)\max_{u,v \in V}\delta(u,v)maxu,v∈Vδ(u,v),其中δ(u,v)\delta(u,v)δ(u,v)代表从u到v的最短路径。也就是树中所有最短路径的最大值。请设计一个算法,求这颗树的直径。分析我们使用两次BFS即可,第一次随机选取一个节点当做为源节点,之后找到里源节点最远的那个节点,就是直径的一个端点。直径要么经过源节点S,要么不经过,我们可以证明原创 2021-01-26 15:56:55 · 370 阅读 · 0 评论 -
图论-关联矩阵
图论-关联矩阵问题有向无环图G=(V,E)G=(V,E)G=(V,E)的关联矩阵是满足下述条件的∣V∣×∣E∣|V| \times |E|∣V∣×∣E∣矩阵B=(bij)B=(b_{ij})B=(bij)。bij={−1如果边j从节点i出发1如果边j进入节点0其他b_{ij} = \left\{\begin{matrix} & -1 & 如果边j从节点i出发 \\ & 1 & 如果边j进入节点 \\ & 0 & 其他\end{matr原创 2021-01-26 15:05:31 · 2168 阅读 · 0 评论 -
图论-通用汇点
图论-通用汇点问题给定一个有向无环图G=(V,E)G=(V,E)G=(V,E)的邻接矩阵表示,给出一个时间复杂度为O(V)O(V)O(V)的算法,判断图是否存在一个通用汇点。通用汇点指的是入度为∣V∣−1|V|-1∣V∣−1但出度为0的点。分析在有向无环图G中,通用汇点如果存在,且只能存在一个。如果存在两个,那么任意一个的入度都不满足∣V∣−1|V|-1∣V∣−1。假设通用汇点为节点i,那么邻接矩阵的第i行全是0,满足出度为0。同理,第i列除矩阵主对角线以外的位置全为1,满足入度为∣V∣−1|V原创 2021-01-26 14:44:06 · 409 阅读 · 0 评论 -
图论-平方图
平方图此文我们讨论一下对一个邻接矩阵进行平方,三次方,n次方的意义和相应的邻接链表的算法。首先我们定义k×kk \times kk×k邻接矩阵GGG,则元素Gxy2=∑i=1kGxk⋅GkyG^{2}_{xy}= \sum_{i=1}^{k}G_{xk} \cdot G_{ky}Gxy2=i=1∑kGxk⋅Gky因此邻接矩阵平方相乘的意义是得到平方图,即有向图G=(V,E)G=(V,E)G=(V,E)的平方图是图G2=(V,E2)G^{2}=(V,E^{2})G2=(V,E2),边(u,原创 2021-01-24 23:24:45 · 2703 阅读 · 0 评论