![](https://img-blog.csdnimg.cn/20190927151132530.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
图论
图论
曼切斯特的流氓
007
展开
-
可达性统计(在有向图中,统计每个点能够到达多少个点)拓扑排序
先求拓扑序,利用拓扑序倒叙,因为拓扑序倒叙才能保证正确的顺序性,比如u—>v,我们一定先求出v能够到达哪些点,然后用v到达点的数量更新u,这也就是利用拓扑序倒叙就可以做到。我们在统计哪些边相连同时,利用bitset数据结构即可存储哪些存在边,更新时只需要f[v]|=f[u]即可更新。bitset数据结构,存放二进制数,比如001011,此类数据。原创 2023-06-04 21:57:59 · 411 阅读 · 0 评论 -
单词环(0/1整数规划)
我们取每个单词的前两个字母,以及后两个字母为节点,单词的长度为边,那么我们可以将规模缩小到,26*26个点,1e5条边这个复杂度小很多。这道题主要是建图困难,如果我们直接建图,那么有1e5个点,1e10条边,肯定超时。原创 2023-05-27 21:49:40 · 128 阅读 · 0 评论 -
观光奶牛(01规划+负环+二分)
这类问题首先要写出表达式,然后将表达式整理位加减法一端>=0或者<=0,此类形式,然后转为图论问题,对图的边权进行调整,最后转为最短路、最小生成树、负环等问题。求正环那么求最长路,让d一直增加,最后最长路边数最终会大于等于n,即可找到正环。原创 2023-05-25 23:18:17 · 144 阅读 · 0 评论 -
虫洞(spfa求负环)
在松弛操作的时候,用一个cnt数组记录最短路边数,如果大于等于0那么一定存在负环,就是因为负环才一直迭代下去,导致最短路长度大于等于n。这道题,出发点任意,那么只要找到一个负环,肯定可以穿越回出发点之前的某一时刻,也就是在负环上作为出发点即可。判断条件:最短路边数绝对不可能大于等于n!s负环:环的权值和小于等于0。原创 2023-05-25 21:38:20 · 111 阅读 · 0 评论 -
走廊泼水节(kruskal+连通块中点的数量)
开辟一个s数组维护连同块中点的数量,合并两个连通块,最后新增的边的权值和等于 (size(u) * size(v)-1) * (w+1),减去1是因为自身已经连同不需要加边。每次新边的权值,一定是当前枚举出的边的权值加上1,不然会破坏原最小生成树。原创 2023-05-25 15:23:49 · 127 阅读 · 0 评论 -
新的开始(最小生成树+超级源点)
我们建立一个超级源点,每个点都与超级源点相连,他们的权值为在该点建立发电站的费用,剩下的将其余点相连,权值为连接到已经通电的发电站费用,我们跑一遍最小生成树即可将他们全部相连,并且费用最小。原创 2023-05-25 12:00:45 · 168 阅读 · 0 评论 -
AcWing连接格点(坐标转为编号,并查集维护)
【代码】AcWing连接格点(坐标转为编号,并查集维护)原创 2023-05-19 16:52:53 · 132 阅读 · 0 评论 -
合适的环(图中度的应用)
我们可以利用一个g数组记录那两个点之间有边,然后枚举第三个点,用一个d数组记录每个点的度,最后求出一个环所连的边的点最少,只需要cnt=d[a]+d[b]+d[c]-6计算即可。根据复杂度无法枚举3个点,所以可以枚举边,变为O(N*M)的复杂度可以通过。原创 2023-05-19 11:12:34 · 113 阅读 · 0 评论 -
联络员(最小生成树Kruskal给出固定的边选剩余的边)
对于已经给出的某些固定的边直接算在里面即可,因为有并查集维护。原创 2023-05-18 21:09:54 · 186 阅读 · 0 评论 -
无向图最小环(floyed解决)
按照集合划分,每次枚举的环最大编号为K,那么这个环是 i到k,k到j,j到i这样一个环,每次算出这个环的长度,递归记录路径即可。Floyd本质也是所有点的枚举一遍通过中间点更新到其他点的距离。总的来说就是把所有的环枚举一遍,比大小。原创 2023-05-18 19:56:31 · 168 阅读 · 0 评论 -
排序(Floyd解决传递包庇)
d(i,j)含义为i<j,那么根据Floyd特点每次利用一个中间点更新其他值,那么比如 i<k,k<j推出i<j ,根据这个特点更新。每次读入一对关系,然后跑一边Floyd,再去判断一下是否矛盾,有未确定的关系。原创 2023-05-18 16:16:02 · 138 阅读 · 0 评论 -
牛的旅行(多源最短路floyed)
也就是i号点所在连同块的最短路最大值,j号点所在连通块最短路最大值,以及i号点和j号点之间的距离。那么有了这个公式那么就迎刃而解了!这道题就是求一个Floyd求出没有加边连通各个连通块之前直径最小,以及加边后连同块直径最小,将两者取max。关键在于加边后如果求直径最小,比如i和j之前不连通,那么在i和j加边后,他们相关的路径最短路最大值应该为。先介绍一个多源最短路中的数组,maxd[i] 这个数组可以求出任意i到达所能够到达的点的最短路的最大值。原创 2023-05-18 14:16:51 · 88 阅读 · 0 评论 -
最短路个数与次短路个数问题
比如这个图,spfa先沿着路线1更新到终点,终点b的最短路径为1,a的最短路径数也为1,然后spfa会沿着路线2更新,那么更新后a的最短路路径数位2,但是此时终点的最短路径数会加上a的最短路径数,那么b的最短路径数位3,显然是不对的。利用一个数组d[i][1] d[i][0] d(i,1)表示i号点的次短路个数,d(i,0)表示i号点的最短路次数。dijkstra是具备拓扑序更新这个特点,因为优先队列保证了每次一个点出队后,他不会在次出队,这样就形成拓扑序。首先spfa不具备拓扑序,他会重复更新。原创 2023-05-12 22:06:51 · 78 阅读 · 0 评论 -
拯救大兵瑞恩AcWing(bfs最短路+坐标编号化+dp状态转移)
分析dp部分:这道题对最短路中d数组进行变化,将它的含义变为编号z它目前拥有钥匙数为s,s是一个二进制数eg s=1010即z编号位置拥有钥匙1和钥匙3,那么我们跑一遍bfs先达n*m终点编号的一定是最短路。对于移动的处理,首先遇见墙肯定不能走,遇见门,我们要用手里的钥匙去匹配也就是((s>>x)&1)==1,门的类型为x,如果等于1那么有这把钥匙,如果等于0那么没有这把钥匙,有这把钥匙正常通过,没有这把钥匙不能通过,其他的与bfs最短路问题没有任何差别。首先要学会横纵坐标转编号。原创 2023-05-12 17:55:11 · 118 阅读 · 0 评论 -
最佳路线AcWing(单源最短路+反向建图)
我们的出发点有许多个,但是终点只有一个,所以我们可以反向建图,化终点为起点,起点为终点,求最短路。原创 2023-05-11 17:50:37 · 80 阅读 · 0 评论 -
道路与航线(单源最短路+拓扑排序中最短路)
如果是一个有向无环图,那么这个图的最短路一定是拓扑序出的最短路,如果一个点入度不为0,那么最短路能去更新他的点一定是与他相连指向它的点,在这个点出队前,那么它的入度点一定都更新过它,所以它一定是最小值。原创 2023-05-11 15:26:22 · 97 阅读 · 0 评论 -
通信线路(分层图)
分层图模板,在判断条件进行更改即可,因为要求。,所以每次转移最大边即可。原创 2023-05-09 20:30:29 · 78 阅读 · 0 评论 -
新年好(单源最短路+全排列枚举方案)
仔细看题目发现需要访问的点一共只有5个,那么即使做5遍最短路复杂度也不超时!做五遍最短路后得出每个亲戚到不同亲戚间的最短距离。这道题的拜访顺序是不固定的,也就是我们要在不同的拜访顺序中找到最小的那一条路线。我们可以全排列出不同的路线,最后按照一个顺序求出每个路线的距离,最后求最小即可。原创 2023-05-09 19:46:51 · 75 阅读 · 0 评论 -
昂贵的聘礼(超级源点+更新限制)
根据1号点的等级,以及题目给出的等级范围m,那么最大间是(level[1]-m,level[1]+m)这个区间直接带入肯定是不合法的,因为level[1]-m不可以和level[1]+m等级的人交易,所以要枚举合法区间从最低的level[1]-m开始一直枚举到level[1] 这个是最低等级,最高等级就是level[1]到level[1]+m。这道题还是建图比较难想出来,首先要明确不论怎么买卖最后终点一定是1号点。跑一边spfa/dij就可以得出到达1号点的最小值。原创 2023-05-09 16:48:45 · 62 阅读 · 0 评论 -
最优乘车(单源最短路+构图)
题目中给出大巴路线,那我们就可以知道一个点可以可以直接到达哪些点,我们直接构建一条边在两点之间即可。比如 大巴路线为4 7 3 6 那么我们在建图时创建 4–>7 4–>3 4—>6 7–>3 7–>6 3–>6这样我们跑一遍最短路可以得出乘坐了几台不同编号的公交车,最后结果减去1就是答案。这道题我们在构图上进行改变,从而简化题目,跑一遍单源最短路就可以得到结果。题目询问换乘次数,也就是乘几台不同编号的大巴数量减1。原创 2023-05-09 13:23:02 · 254 阅读 · 0 评论 -
最小花费AcWing(最短路判断条件改变)
这也就是使这个式子中w1 * w2 * w3 * …* wn最大那么在判断的时候更改判断条件即可。最终花费变为100,求初始值X最小,100=X * w1 * w2 * …原创 2023-05-09 12:02:02 · 81 阅读 · 0 评论 -
机房(树上两点间距离)
LCA倍增原创 2023-03-23 02:19:17 · 106 阅读 · 1 评论 -
图论算法总结
图论算法考研模板原创 2022-09-23 19:41:14 · 332 阅读 · 0 评论 -
链式前向星存图(有图详解)
链式前向星:既然是链式那么肯定和链表相关,前向星是每次指向都向前链式前向星存图是以边为中心,并不是以结点为中心,它记录的是边的一些属性,包括边边的id、头节点、尾结点、权值、边的指向!边的指向是遍历图的时候需要按照一定顺序去遍历,而不能胡乱的去遍历,那么就需要这些边存在一定规律,所以用到"边的指向",这个指向是相同头节点出发,依次指向相同头节点的边,下图为例。通过这幅图我们可以看到v1、v2、v3、v4都是由结点u出发,引出的边1、边2、边3、边4,可以看到橙色的指向箭头,边4指向边3、边.原创 2021-09-25 20:18:08 · 4032 阅读 · 0 评论 -
分层图(图解+例题)
分层图分层图多用于求最短路径,但是最短路径中可以有k条边的权值为0。既然可以k条边为0,那么对于k条边的选取就是个问题。所以有了分层图的概念。对于每个点都可以选择下一条边是否赋予权值为0,那么我们就可以将图画出k+1层。图例我们简单画一下一个有向图,并且k=1(有一条边权值可以为0)(这是初始情况,接下来我们分层)k=1,我们要分k+1层我们模拟从0开始,0可以走的路路径我们可以看到,如果走同一层,那么权值就要+5或这+100,如果向上一层走那么要加上权值0,并且k减减,也原创 2021-04-11 20:26:55 · 5829 阅读 · 9 评论 -
最优贸易(SPFA反向图)
题目:题目传送门C国有n个大城市和m 条道路,每条道路连接这 n个城市中的某两个城市。任意两个城市之间最多只有一条道路直接相连。这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道路在统计条数时也计为 1条。C国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。商人阿龙来到 C 国旅游。当他得知同一种商品在不同城市的价格可能会不同这一信息之后,便决定在旅游的同时,利用商品在不同城市原创 2021-04-11 13:40:48 · 415 阅读 · 1 评论 -
拓扑排序
拓扑序列:定义:将图中顶点以线性方式进行排序,对于任何使得从顶点u到顶点v的有向边,顶点u总是排在顶点v的前边,这样得到的序列叫拓扑序列。显然能瞒住拓扑序列的图都是有向无环图简称DAG。所有DAG存在一个或多个拓扑序列。图例:这是一个有向无环图(DAG),我们可以根据拓扑序列定义得到几组拓扑序列1、3、2、5、4、6、73、1、5、2、4、7、6为什么会出现多组拓扑序列呢?我们观察上图可以发现1、3这两个结点没有任何关系,不存在指向关系,所以他们两个是并列关系,我们可以原创 2021-04-10 15:28:29 · 227 阅读 · 2 评论 -
Floyed算法
Floyed-Warshall算法定义floyed主要解决多源最短路径问题,可以求出任意两点间的最短路径,以简单便捷著称!实现过程floyed的实质是动态规划思想(将小规模问题的解存储在内存中,等到大问题的解直接拿来有效利用,这就是动态规划的基本思路),floyed通过3层for循环,先确定k值,然后每一个起始结点u,通过k到达v(d[u][k]+d[k][v]),与原来的d[u][v]进行比较选出较小的值。主要代码for(int k=1;k<=n;k++)for(int i=1原创 2021-04-08 20:36:27 · 3132 阅读 · 0 评论 -
SPFA算法
SPFA算法:主要是为了求解图中的单源最短路径(可以含负权边),是对Bellman-Ford 的优化,但无法完全取代Bellman-Ford。SPFA算法可以解决,Dijkstra算法无法解决的权值为负的情况。为什么出现负权值dijkstra算法失效我们看张图,从1号结点开始执行dijkstra算法,我们在权值6和5的边中选择,权值为5的边此时来到二号结点d[2]=5,然后选择边权为-2的边更新d[3]=3,结束dijkstra算法。我们可以看到结束时d[2]=5,而实际上d[2]应该=4才是原创 2021-04-08 18:45:04 · 406 阅读 · 0 评论 -
Kruskal算法
Kruskal算法kruskal算法是从边出发,先将所有边的权值从小到大排序,然后依次添加进图中,在添加过程中要判断是否形成环。Kruskal算法视频讲解代码实现Kruskal算法四步法1、先将所有的边拿出来,按权值进行排序2、遍历所有的边3、在遍历过程中利用并查集FindFather操作判断是否形成环4、如果遍历的边数量为n-1(n个结点,n-1条边)停止遍历求出最小生成树。代码:#include<bits/stdc++.h>using namespa原创 2021-04-06 19:59:16 · 219 阅读 · 0 评论 -
Dijkstra狄克斯特拉-最短路径问题
教学视频狄克斯特拉算法与prim普里姆算法的不同之处这两种算法大同小异,prim算法是求最小生成树,在每一次取点的时候,判断两点之间的距离,选出距离最小点,作为起点遍历,然后更新d数组,只需要更新起点,到这个点的最小距离给d[v],而dijkstra算法需要从题目给出起点到该点的最小距离更新d[v],也就是d[v]与他的父亲结点的d[v]息息相关!注意:dijkstra算法不能用于权值为负的情况。prime和dijkstra算法都是O(V^2),在没有优先队列优化的情况下。代码实现:原创 2021-04-05 22:09:17 · 431 阅读 · 0 评论 -
普里姆(prim)算法--求最小生成树
教学地址:普里姆算法代码实现:#include <bits/stdc++.h>using namespace std;const int maxn=110;int n,M[maxn][maxn];int vis[maxn];int d[maxn],p[maxn];int minv,u;int prim(){ for(int i=1;i<=n;i++) { vis[i]=0; d[i]=0x7f7f7f7f; p[i原创 2021-04-05 14:58:23 · 387 阅读 · 0 评论 -
Connected Components-连通分量(挑战程序设计竞赛)
题目:请编写一个程序,输入SNS的朋友关系,判断从指定人物出发能否通过双向朋友链抵达人物。输入: 第1行输入代表SNS用户数的整数n以及代表朋友关系数的m,用空格隔开。SNS各用户的ID分别为0到n-1。接下来的m行输入朋友关系,每个朋友关系占1行。1个朋友关系包含s、t这两个整数,表示s和t为朋友。s、t输入时用空格隔开。紧接下来的1行输入问题数q。再接下来的q行输入问题。各问题均为用空格隔开的2个整数s、t,表示从s出发能否抵达t?输出: 如果从s出发能抵达t就输出yes,否则输出no,每个原创 2021-04-04 21:07:53 · 364 阅读 · 0 评论