图论
文章平均质量分 74
荼白777
这个作者很懒,什么都没留下…
展开
-
找最大环、最小环、第一次出现的环
Link-Cut Tree传送门本题是找第一次出现的环;题面思路二进制有一个常见的性质21+22+...+2i<2i+12^1+2^2+...+2^i <2^{i+1}21+22+...+2i<2i+1那么本题其实也就是要我们求第一次出现的环;那么考虑用并查集来处理(类似Kruskal),然后dfs一次;Code#include <iostream>#include <cstring>#include <cstdio>#i原创 2022-04-05 21:37:50 · 454 阅读 · 0 评论 -
二分图判定&二分图最大匹配模板
二分图定义可以把所有的点划分成两个集合,集合内部不存在边,集合之间存在边;01染色判定二分图性质一个图是二分图等价于不存在奇数环奇数环是指点的个数是奇数的环,如下图;有一个通俗的解释,奇数个点无法被两种颜色均分;那么我们的做法很简单,如果一个点没有被染色,那么我们将它(记为uuu)染为白色,将与uuu相连的点染成黑色;不断重复这个过程即可,若过程中发现同色相连,那么就产生矛盾了;染色法判二分图题面Code#include <iostream>#include原创 2022-03-31 21:28:53 · 654 阅读 · 0 评论 -
二分图例题
常见问题最小点覆盖、最大独立集、最小路径点覆盖(最小路径重复点覆盖);注意二分图一般是指无向图,后续例题虽然存在有向图,但是思路还是无向图的;常见性质一个图是二分图等价于图中不存在奇数环等价于染色法不存在矛盾最大匹配数 = 最小点覆盖 = 总点数 - 最大独立集 = 总点数 - 最小路径覆盖例题关押罪犯传送门二分 + 染色法判定二分图题面思路把罪犯看成点,把仇恨关系看成边,仇恨值看成边权;那么问题就转化为将所有点分成两组,使得各组内边的权重的最大值尽可能小;因为这是一原创 2022-03-31 20:46:52 · 901 阅读 · 0 评论 -
负环 —— SPFA扩展
负环的定义在有向图或无向图中,存在一个环,权值之和为负数;那么按常规最短路,就会无限在这上面更新了,也就是使得dist(u)=−INFdist(u) = -INFdist(u)=−INF负环的问题最经常结合01分数规划;方法建议使用第二种方法,一般来说,方法二跑的比较快;方法一解释这个方法是由Bellman−FordBellman-FordBellman−Ford扩展过来的;BF算法告诉我们,如果我们迭代了nnn次,还有节点没更新,那么说明存在负环;而我们的SPFA是基于BF算法的,在原创 2022-02-22 17:43:59 · 433 阅读 · 0 评论 -
最小生成树的扩展应用
引入首先介绍一个定理,以及一个它的推论;定理:任何一颗最小生成树一定包含无向图中权值最小的边推论:给定一张无向图G=(V,E)G=(V,E)G=(V,E),n=∣V∣n=|V|n=∣V∣,m=∣E∣m=|E|m=∣E∣。从EEE中选出k<n−1k<n-1k<n−1条边构成GGG的一个生成森林。若再从剩余的m−km-km−k条边中选n−1−kn-1-kn−1−k条添加到生成森林中,使其成为GGG的生成树,并且选出的边的权值之和最小,则该生成树一定包含这m−km-km−k条边中连接生成森林的两个不连通节原创 2022-02-16 14:50:25 · 536 阅读 · 0 评论 -
最小生成树的基础应用
Prim&Kruskal的一个核心思想Prim是每次选择距离最近的边,然后加进来;Kruskal是将边权升序排序,每次连接两个不连通的点;那如何证明这样选择边是正确的?这两个算法的证明思路都是一样的;假设不选当前这条边,最终得到了一棵树,我们将当前这条边加上,必然会形成环;在这个环上,一定可以找出一条长度不小于(因为按两个算法,我们这条边都是最小的)当前边的边,我们用当前这条边去替换找到的这条边,结果一定不会变差(最坏不变,可能变小);例题Kruskal适用于稀疏图,Prim适用于稠原创 2022-02-14 10:57:26 · 2951 阅读 · 0 评论 -
Floyd算法思路以及扩展应用
牛的旅行传送门这题是Floyd的简单扩展;题面思路题目要求我们连一条边以后,使得新牧场的直径最小;假设左边牧场的直径为d1d_1d1,右边牧场的直径为d2d_2d2;因为我们要将这两个牧场连起来,那么假设新的直径为d3d_3d3;必然有d3≥max(d1,d2)d_3 ≥ max(d1,d2)d3≥max(d1,d2);因为要求最小,我们期望相等;假设连边以后,构成了一条新的直径;那么组成必然是距离左边点的最远距离+这条路径长+距离右边点的最远距离;我们想要相等,要原创 2022-02-07 17:15:20 · 1023 阅读 · 3 评论 -
最短路计数类问题 —— 最短路扩展
最短路计数题面思路和DP中的计数问题类似;首先我们得先求出最小值是多少;再求出当前这个状态能由哪几个状态转移最小值过来;需要注意,DP问题都是满足拓扑序的,但是图论的问题不一定;因此我们要满足更新是符合拓扑序的;最短路计数首先满足条件是不能存在值为0的环,因为存在的话那么被更新的点的条数就为INFINFINF了;接着,我们需要把图抽象成最短路树,或者称为拓扑图;而我们求最短路一般有三种方法;BFS,适用于边权为1的情况;迪杰斯特拉系列(包括0-1BFS),适用于非负权图;原创 2022-02-05 21:32:55 · 523 阅读 · 0 评论 -
拯救大兵瑞恩 —— 最短路扩展 DP + BFS
拯救大兵瑞恩题面思路假设没有钥匙和门的概念,这题就是最基础的迷宫问题(从左上到右下一个BFS即可);现在引入了钥匙和门的概念;假设我们当前在(x,y)(x,y)(x,y),要前往周围的四个格子,但是我们只用(x,y)(x,y)(x,y)是无法表示我们手上有几把钥匙的;看到钥匙的种类最多为101010,考虑状压来表示;我们用dist(x,y,s)dist(x,y,s)dist(x,y,s)表示从点(1,1)(1,1)(1,1)出发到点(x,y)(x,y)(x,y)且拥有的钥匙集合为sss的原创 2022-02-05 17:20:56 · 822 阅读 · 0 评论 -
选择最佳线路 ——单源最短路扩展,多个起点
最短路原创 2022-01-30 14:56:50 · 992 阅读 · 0 评论 -
Kruskal重构树学习
引入简单来讲,就是在Kruskal算法进行的过程中,我们把最小生成树的边权改为点权;可以看成是Kruskal算法的扩展使用;假设原树有nnn个结点,因为最小生成树是n−1n-1n−1条边;那么重构树有2n−12n-12n−1个结点;举个例子,比如xxx到yyy连了一条边;那么重构以后变成这样;性质是一个小/大根堆(由建树时边权的排序方式决定)所有原来的点是叶子节点LCA(u,v)LCA(u,v)LCA(u,v)的点权是 原图uuu到vvv路径上最大边权的最小值或者最小边权的最大原创 2021-12-02 00:45:52 · 540 阅读 · 1 评论 -
DP与最短路联系 && 最优贸易 —— DP + 最短路
DP与最短路联系以0−10-10−1背包为例转移方程为f(i,j)=max(f(i-1,j),f(i-1,j-w)+v)可以看成图论中的路径;有以下关系;这启发我们,如果一个DP问题的依赖关系不具有拓扑序,那么我们可以用最短路算法来解决这种DP不能解决的问题;比如说像下图这种形成了环路的,用DPDPDP是没法解决的;但是我们可以用最短路来解决;题面传送门思路要求一次买入卖出可以得到的最大收益;我们设定集合为先买后卖的所有方案中的最大值;将上述集合划分成若干个子集;原创 2021-11-24 23:44:30 · 814 阅读 · 0 评论 -
道路与航线 —— 最短路 + 拓扑 + FloodFill
题面传送门思路这道题SPFA会被卡,因此我们得考虑其他办法;道路的特点:双向边,可能有环,边权非负航线的特点:单向边,无环,边权可正可负由此,我们认定只有道路的连通块是一个团;也就是说在这个团内部,由于边权都是非负的,因此我们可以跑迪杰斯特拉;而团与团之间是航线(有向边)连接的,如果我们将团看成一个整体,那么这就是一个DAG;如图所示;由于是DAG,或者说是拓扑图,我们按照拓扑序的方式去更新一个个团,就可以得到最短路了;采用拓扑序线性更新最短路,是可以处理负权边的(因为每个点原创 2021-11-24 21:15:25 · 491 阅读 · 0 评论 -
通信线路 —— 二分+最短路
题面思路这题其实是让我们求某条路径上第k+1k+1k+1大的边权最小是多少;这种最大值最小的问题,我们考虑二分来解决;我们猜一个值xxx,如果比xxx大的边权小于等于kkk条;那么我们就往左边走,否则我们就往右边走;解释:往左走xxx变小,那么大于xxx的边权数量就会增加;右边同理;现在考虑如何求从111到nnn要经过多少条边的边权小于等于xxx;我们将这些边分为两类大于xxx的边权,边权赋为1小于等于xxx的边权,边权赋为0这样我们从111到nnn跑一条最短路;就可以知原创 2021-11-24 19:17:02 · 301 阅读 · 0 评论 -
新年好 —— 最短路 + DFS
题面传送门思路预处理以自己家和555个亲戚家为起点的,到其他点的最短路(跑6次迪杰斯特拉);接着dfs拜访顺序,一共是5!5!5!次,并不是很大;也就是dfs枚举全排列;Code#include <iostream>#include <cstdio>#include <cstring>#include <map>#include <algorithm>#include <queue>#include <原创 2021-11-23 20:06:38 · 153 阅读 · 0 评论 -
昂贵的聘礼 —— 最短路变形
题面思路这题难在建图上;我们可以这样建图;虚构一个源点,以下称为虚拟源点;由虚拟源点向各个点连一条边,边权为直接购买这个物品的价格;对于每个物品来说,由替代品向该点连一条边,边权为需要补的差价;比如说这是样例的建图;有了上述图以后,现在考虑怎么处理等级,因为数据不大,我们直接枚举;我们可以枚举等级区间,保证111号点在等级范围内即可;然后就是一个从000号点出发到111号点的最短路;000号点就是我们所说的虚拟源点;Code#include <iostream>原创 2021-11-23 19:07:09 · 58 阅读 · 0 评论 -
最优乘车 —— 建图BFS
题面思路对于每一条单向的巴士线路来说,前面的站点可以到达后面的站点,而反之不行;因此对于每条线路来说,我们可以用前面的点向后面的点连一条边权为111的边,然后搜索;因为边权只为1,因此我们可以用bfs来解决;Code#include <iostream>#include <cstdio>#include <cstring>#include <sstream>#include <queue>#include <algo原创 2021-11-22 22:08:47 · 372 阅读 · 0 评论 -
最小花费 —— 最短路变形
题面传送门思路假设起点为SSS,终点为TTT;题目想问SSS最少是多少;在满足S∗w1∗w2∗...=T=100S*w_1*w_2*...=T=100S∗w1∗w2∗...=T=100的情况下;其中wiw_iwi是边权;要使得SSS最少,说明w1∗w2∗...w_1*w_2*...w1∗w2∗...要最大;即Smin=100(w1∗w2∗...)maxS_{min} = \frac{100}{(w_1*w_2*...)_{max}}Smin=(w1∗w2∗...)max原创 2021-11-22 11:44:42 · 423 阅读 · 0 评论 -
Floyd模板
引入Floyd是可以处理负权图的;但是不能处理带有负权回路的;题面传送门Code#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>using namespace std;typedef long long ll;const int N = 2e2 + 10;const int IN原创 2021-11-19 23:01:09 · 408 阅读 · 0 评论 -
SPFA例题
引入SPFA的核心思想是优化dist[a]=min(dist[a],dist[b]+w)这个式子;不难想到,如果我们想要优化dist[a],那么只能从dist[b]+w这个式子转移过来;也就是说,只有dist[b]变小了,才有可能优化dist[a];即只有一个点被更新过后,我们才拿这个点更新其他点;基于这个思想,我们来实现SPFA;注意带有负边权的图只能用SPFA时间复杂度一般为O(kE),k是常数O(kE),k是常数O(kE),k是常数;最坏情况下是O(VE)O(VE)O(VE)例原创 2021-11-19 22:08:17 · 537 阅读 · 0 评论