图论算法
文章平均质量分 80
基础图论算法
harry1213812138
有任何问题可以评论,我会第一时间回复。
在下虽然菜,但是菜的认真。
展开
-
最小路径覆盖与最小链覆盖 Dilworth定理:最小链覆盖等于最长反链(详细证明与经典例题)
一、最小路径覆盖定义最小路径覆盖就是指在有向无环图中,用最少的、不相交的简单路径覆盖图中的所有点。解法①将原图中的每个点拆点,(将点u拆成u与u+n);②将原图中的每条边 <u,v> 在新图中建立对应的边 <u,v+n>;③将点(1 ~ n)作为二分图的左部,将点(n+1 ~ 2*n)作为二分图的右部,进行二分图的最大匹配;④所求的最少路径数等于总点数n 减去 最大匹配数。二、最小链覆盖定义最小链覆盖和最小路径覆盖的区别是,最小链覆盖允许路径相交。最小路径覆盖原创 2021-12-29 19:53:54 · 2563 阅读 · 0 评论 -
最短路变形 加法换成乘法 求连续相乘最短路与最长路总结
乘法最短路问题普通的最短路问题是将路径上的所有边的权值相加,求最小权值和的一条路。但这里的变形是将加法换成乘法,求最小权值积的一条路。这里我们可以用dijkstra或spfa来做,只是将加号换成乘号即可。我们的更新语句就是:if(dis[v] > dis[u] * w[i]) //v是循环的点,u是上一次被修改过的点{ dis[v] = dis[u] * w[i];}注:这里保证所有边的权值都是非负数,因为一旦出现负数,相乘之后最小值会变成最大值,最大值会变成最小值,就非常难了,需要同时原创 2021-04-05 12:14:06 · 532 阅读 · 2 评论 -
最小权点覆盖集 与 最大权独立集
一、最小权点覆盖集这里我们来看特殊的最小权点覆盖集,就是对于二分图而言的。什么是点覆盖集呢?就是图中所有点的一个子集,首先他是一个点集,然后图中所有边的两个端点的其中一个都在这个点集中,就是说这个点集覆盖了所有边。那么对于每个点我们给他一个权值,所有点覆盖集中,总权值和最小的一个就是所说的最小权点覆盖集。二、具体做法我们利用最小割来求解最小权点覆盖集,首先我们是在二分图上来做,其次所有点权都要是正数(要做网络流的流量)。我们将所有二分图的点看成两个集合X和Y,从s向所有X集合的点连一条容量为点权的边,原创 2021-02-27 18:17:13 · 3989 阅读 · 0 评论 -
最大密度子图
最大密度子图首先要了解什么是最大密度子图,顾名思义,就是所有子图中密度最大的那一个。那么什么是一个子图的密度呢,这里规定子图的密度就是子图中边数和点数的比值。原创 2021-02-24 17:17:10 · 2162 阅读 · 0 评论 -
最大权闭合子图
闭合图首先,先了解什么是闭合图。闭合图一般指一个图中点的集合,从该集合中所有的点出发,能到达的点要求都必须在该点集中。也就是说,从该集合中出发,一定要回到该集合中,不能出到集合外。最大权闭合图,顾名思义,就是所有闭合图中点权之和最大的那个,注意这里的权指的是点权,因为闭合图是对于点集而言的。...原创 2021-02-20 15:37:33 · 2284 阅读 · 0 评论 -
网络流常用小技巧之 拆点
一、什么是拆点拆点就是将一个点拆成入点和出点两个点,并在两个点之间建一条边。二、为什么要拆点拆点是为了实现对点的限制。三、什么时候需要拆点如第二点,当题目中明确说明对点有限制或在实际应用中对点有限制时,我们就需要拆点。例如我们要保证经过某点中转的流量不能大于5(对点有流量限制),那么我们就需要将该点拆成入点和出点,并在两点间建一条容量为5的边,就实现了对点的限制。四、总结做题时一定要看清,如果是对边有限制,就通过流量或流网络来实现;如果是对点有限制,就通过拆点来实现。五、例题分析acwin原创 2021-01-29 22:49:02 · 803 阅读 · 0 评论 -
一篇网络流 基本模型超全总结(最大流 费用流 多源汇最大流 上下界可行流) 思路+代码模板
一、网络流与最大流网络流(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关。在一个有向图中,一个源点S到一个汇点T之间有连边,边的权值是该边的最大容量,网络流就是从S点到T点的一个可行流。网络流最初的问题就是研究最大流,就是指所有可行流里面最大的流。举个简单的例子,如下图:若v1到v6六个点表示的是六个城市,每条边的权值表示的是城市之间路的长度,选择要运送一批物资从v1到v6,要走的路最短这就是最短路问题。但是如果v1到v6表示的是六个中转站,每条边表示的是水管,权值原创 2020-12-06 09:53:27 · 11119 阅读 · 6 评论 -
最大流 dinic算法的优化(当前弧优化)思路+代码模板
Dinic算法普通的dinic算法在有些时候会被卡掉,因为每次dfs太多了,所以对此就有了当前弧优化来解决这个问题。什么是当前弧优化当前弧优化就是说我们在每次dfs找的时候,把已经榨干的点删掉,我们直接从可以增加流量的边开始。假设我们的残留网络已经更新成现在这个网络了,假设源点s出发的有编号1、2、3号边,1和2号边都无法再增加流量了,没有用了(相当于这两条边被榨干了),那么我们在下次bfs得到的分层图再dfs找增广路时,就不考虑1和2号边了,直接从s出发去3号边找。就能省略很多层递归。当前弧优原创 2020-11-29 23:39:56 · 2334 阅读 · 3 评论 -
Tarjan 算法思想求强连通分量及求割点模板(超详细图解)
割点定义在一个无向图中,如果有一个顶点,删除这个顶点及其相关联的边后,图的连通分量增多,就称该点是割点,该点构成的集合就是割点集合。若在图G中(如下图),删除uv这条边后,图的连通分量增多,则u和v点称为割点,uv这条边称为桥或割边。显然,有割点的图不是哈密尔顿图。...原创 2020-11-09 21:24:47 · 831 阅读 · 0 评论 -
图论最短路径之Floyd算法
Floyd算法主要思想我们在求任意两点间的最短路径时,可以循环一遍所有点,轮流作为源点,然后用dijkstra或bellman算法求解,时间复杂度是O(n3),也可直接使用Floyd算法,更直接,时间复杂度也为O(n3)。Floyd的代码很简单,其核心代码只有5行:for(int k = 1;k <= n;k++) //循环1-n所有顶点 for(int j = 1;j <= n;j++) //循环终点 for(int i = 1;i <= n;i++) //循环起点 i原创 2020-10-07 21:40:00 · 633 阅读 · 0 评论 -
图论之分层图最短路总结 与经典例题
一、分层图分层图只是建图时有区别,但跑最短路板子都是一样的,正所谓图论最难的就是建图,只要有合适的建图方法,那么问题就很简单了。分层图是指有很多个平行的图,各个平行的图之间有特殊的连接边。用分层图的几种情况:1、有k个不同集合的边,将每个集合内的边建成一张图,再建立第k+1个图,是一个虚层,用这个虚层将这k张图连接起来。每次可以通过虚层转移到另一个集合的图中。如例1.小雨坐地铁。2、有k个机会使得走当前此边不花费代价或花费特殊的代价,可以建立k张相同的该图,每张图之间用有边的点连接起来,其代价是0或是原创 2020-08-28 17:19:55 · 4690 阅读 · 2 评论 -
图论最短路径之SPFA算法 bellman算法的队列优化
一、SPFA算法思想SPFA算法就是队列优化的Bellman-Ford算法,减少了不必要的冗余判断。大致流程是用一个队列来维护,先将源点入队,然后每次从队列首取出一个点,将该点的所有出边(就是以该点为起点的边)松弛,若某条边松弛成功,就将该边的终点入队,重复此过程,直到队列为空结束。...原创 2020-07-24 15:17:11 · 210 阅读 · 0 评论 -
图论最短路径之Bellman-Ford算法 代码模板及其优化
一、对比dijkstra算法1、dijkstra算法的局限性dijkstra算法适用的图不能含有负权值的边,若含负权值,可能会导致求得的答案错误。如下图:以0为源点,首先确定到最近的2号点距离为5,然后确定到1号点的距离为7。但实际到2号点可经过1号点中转,经过负权值的边到2号点的距离为2 。所以当图中出现了负权值的边,就要用Bellman-Ford算法。2、Bellman-Ford算法的局限性Bellman-Ford算法的图中不能有负权值回路(总权值和为负数的回路),如下图:此图中0到1出原创 2020-07-22 16:54:21 · 362 阅读 · 0 评论 -
最小生成树 克鲁斯卡尔(kruskal)与普里姆(prim)算法实现及代码实现
一、最小生成树是什么1、生成树:若一个无向连通图G的子图是包含了G的所有顶点的一棵树,则该子图是G的生成树。生成树是图的极小连通子图。简单来说就是删去所有成环的边,使得G变为无环图。2、最小生成树:对无向连通图的生成树中所有边权值和最小的树。最小生成树有三大算法:克鲁斯卡尔算法(Kruskal)、普里姆算法(Prim)、Boruvka算法二、克鲁斯卡尔算法(Kruskal)1、算法思想:克鲁斯卡尔算法以边为主导。设有n个顶点的联通网络G(V,E),①先将所有点取出,构造一个n个顶点0条边的全不原创 2020-07-14 16:26:21 · 557 阅读 · 0 评论 -
图论之图的存储 邻接矩阵、邻接表和链式前向星
一、图的存储方式目前常用的图的存储方式有两种,邻接矩阵和邻接表存储。边数M小于顶点N平方的图为稀疏图,反之为稠密图。稀疏图可用邻接表存储,稠密图可用邻接矩阵存储。邻接表可用数组或链表实现,邻接矩阵可用二维数组实现。二、邻接矩阵1、邻接矩阵简介邻接矩阵很好理解,实质是用二维数组来存储一个图的各边的信息,例如用矩阵e[ i ][ j ]来存储,其中下标i是指一条边的起点的编号,而下标j就是该边终点的编号,e[ i ][ j ]的值存的是该边的权值。用邻接矩阵既可以存储无向图,也可以存储有向图。例如原创 2020-06-05 15:00:05 · 930 阅读 · 0 评论 -
图论最短路径之迪杰斯特拉算法 Dijkstra及堆优化
一、迪杰斯特拉算法简介Dijkstra算法是在图论中求一个顶点到其余各顶点的最短路径的算法,解决的是带权图中(有向无向均可)最短路径的计算,该算法需要求图中无负权边,目前是最快的单源点最短路径算法,时间复杂度是O(n2) 。其特点是从起点开始,用贪心的策略连接最近的且未被访问过的顶点,直到扩展到终点为止。二、实现原理1、基本原理借助一个一维数组存储所求顶点到各个顶点的初始距离,然后找到离所求点距离最近的点为确定距离,再借助这个点所能到的所有点,判断借助最近的点中转到和直接到哪个距离最近,将最近的存储原创 2020-06-07 10:20:35 · 938 阅读 · 0 评论 -
拓扑排序原理及代码实现 经典例题(邻接矩阵 加 邻接表实现)
一、拓扑排序定义: 拓扑排序是将一个有向无环图的所有顶点排成一个线性队列,并且保证队中的所有点不会指向其前面的点,即所有边只能是某个点指向其队列后面的点。排序原理: 首先存下所有点的入度(有几条边的终点是该点),若某点入度为0,将该点加入拓扑序,然后删除该点为起点的所有边(就是将所有该点为起点的边的终点的入度减一),然后重复此操作,直到所有顶点进入拓扑序即可。若有点未进入拓扑序,说明该图存在环。二、代码实现1、邻接表的拓扑排序#include<iostream>#include<原创 2020-05-22 09:30:00 · 1225 阅读 · 1 评论