Graph 图论
文章平均质量分 62
# Graph 图论
daq0411
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
The 15th Chinese Northeast Collegiate Programming Contest - K.City
虽然不难,但是感觉很有意思的一道题,下面有几个点感觉还是挺妙的:· 并查集只能加边不能减边;·对数据进行离线处理,方便我们进行排序处理(后面会解释);首先数据的范围很大,如果我们每做一次判断都要进行一次遍历的话时间复杂度肯定会超时,所以我们想能不能像预处理那样只需要做一次就能得到所有我们想要的答案呢?首先我们先对所有边进行一个从大到小的排序,所以我们在判断毁掉了多少条路的时候只需要判断当前边的值是否小于毁灭的值即可,如果不能毁掉那么后面的也无法破坏,break就好。那么还是没有解决 O(t *..原创 2021-08-22 21:05:14 · 492 阅读 · 0 评论 -
P1169 [ZJOI2007]棋盘制作(悬线法)
昨天做了做杭电多校联赛有一道关于悬线法的题,看到这个洛谷推荐悬线法的题目补一篇题解吧这道题跟杭电多校的那道题感觉差不多,但是有一点区别就是要求矩阵内黑白相间,所以我们在计算高度的时候注意一下颜色即可。1、对矩阵做合法标记处理首先我们先对所给矩阵的颜色进行一个处理:(0,0)设置为1如果这一行是第一行,那么如果(i,j)的颜色跟(i,j-1)的颜色不同,那么说明合法,则标记与(i,j-1)相同,反之则取非;如果这一列不是第一行,那么就跟他的上一行的同一列的颜色作比较,如果(i,j) 的颜色与(i原创 2021-07-26 10:25:58 · 137 阅读 · 0 评论 -
KD-Graph(并查集)
这道题难倒是不难,主要是题目的意思可能不太好理解,就是有n个点,m条边,分成k组,每组至少有一个点,这时我们有一个值d,保证在同一个组内的点之间的边都要小于等于这个d,不在同一个组的点之间的边都要大于这个d,我们可以通过并查集的方法对这个d值进行一个查找:我们先对所有的边进行一个从小到大的排序,然后每次处理边相同的点进行集合合并,如果这一组(边相同的若干条边)处理为之后分成的集合数大于K,那么继续进行,如果等于K,说明KD图存在,如果小于K,说明KD图不存在,输出-1即可。完整代码如下:#in..原创 2021-07-25 23:10:32 · 264 阅读 · 0 评论 -
Maximal submatrix(悬线法)
这道题实质是就是求一个最大子矩阵,参考了很多悬线法的代码,这里介绍一个我感觉很妙的方式,首先我们要知道什么是悬线法:悬线,就是一条竖线,这条竖线要满足其上端点在矩形的上边界或其上端点的上面是障碍点。我们枚举每个点的悬线,求出其最多能向左和向右扩展到何处,取最大值,就能求出最大子矩阵了。通俗的说就是你有一条线,这条线的长度固定,可以左右移动,看他最多能扫过的面积就是我们要求的最大子矩阵的面积。我们可以对已知矩阵进行预处理:up[i][j]: 坐标是(i,j)的这个点最大可以往上的长度,因为要求每一.原创 2021-07-25 22:55:08 · 737 阅读 · 1 评论 -
Minimum spanning tree
这道题看起来是求最小生成式(虽然事实的确是这样),但是跟最小生成树的算法没有什么太大的关系,只需要直到最小生成树的基本定义和素数相关的内容即可,最小生成树的定义如下:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。链接:完整定义与相关介绍了解了最小生成树的定义之后来解释为什么说还要用到素数相关的知识,在大于1的整数中一个数不是质数就是合数,如果一个数是合数,那么与这个相关数的最小公倍数就是他本身(例如4:2(4的因数)和4的最小..原创 2021-07-25 22:10:03 · 277 阅读 · 0 评论 -
次小生成树 Kruskal
Graph 图论次小生成树 Kruskal1、初始化:对并查集进行初始化;for(int i=1;i<=n;i++){ f[i] = i;}对vis数组初始化;对graph数组进行初始化for(int i=1;i<=n;i++) { graph[i].clear(); graph[i].push_back(i); }2、对边进行排序;sort(map,map+m,cmp);3、判断当前边的两个节点是否已经属于同一集合,如果不属于:①这条边标记为使用;②把这两个点所在的集合统一为原创 2021-01-27 23:29:38 · 297 阅读 · 0 评论 -
次小生成树 Prim
Graph 图论次小生成树 Prim我们最常见的是最小生成树,我们最长使用的是Prim和Kruskal算法,一个是对点进行处理,一个是对边进行处理,对于次小生成树来说我们同样可以使用这两个方法进行处理,这里我们先以Prim的写法为例。首先我们要清楚的是什么是最小生成树:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。所以在这之前我们需要先了解几个结论:①如果我们要换掉其中的一条边的话新得到的生成树的权值之和一定小于等于原最小生成树的原创 2021-01-26 23:56:03 · 311 阅读 · 3 评论 -
kruskal 最小生成树
Graph 图论kruskal 最小生成树相对于prim算法对于图中的点进行处理,kruskal则是对于边进行处理,我们在使用kruskal进行处理的时候,需要用到并查集的思想,后面我们会说。kruskal算法实现的大致思路是先对边进行从小到大排序,如果这条边的起点和终点已经在一个集合了,说明加上这条边不会增加新的点对于当前这两个点所在的集合,如果这两个点属于同一个集合,那么把这条边连起来之后会让两个集合变成同一个集合(我们的目的不就是把所有点通过边归到一个集合里面吗),重复此操作直到加入集合的点达到原创 2021-01-24 12:28:27 · 407 阅读 · 0 评论 -
Prim 最小生成树
Graph 图论Prim 最小生成树其实最小生成树的写法跟Dijkstra很类似,就是需要改一个地方就可以:if(dist[b.to]>b.cost){ dist[b.to] = b.cost; }Dijkstra的写法是if(dist[b.to]>dist[node]+b.cost){ dist[b.to] = dist[node]+b.cost; }其他的都一样,因为Dijkstra需要计算的是从源点出发到每个点的最短距离,所以我们需要的是边的长度之和,而最小生成树的原创 2021-01-24 10:07:27 · 194 阅读 · 1 评论 -
dijkstra + A* 第k短路
Graph 图论第k短路今天好懒啊,不想补了……但是怕忘了,先把笔记挂上日后补上吧(狗头保命),但是启发式搜索的确挺有意思的一个算法。(一定补一定补)#include<iostream>#include<queue>#include<vector>#include<cstring>using namespace std;int n,m,begin,end,k;struct edge{ int b; int cost;};vector原创 2021-01-22 21:15:20 · 252 阅读 · 0 评论 -
Dijkstra最短路计数
Graph 图论Dijkstra最短路计数我们最常用的dijkstra是来算单源最短路径,也就是最短路径的长度,如果我们要计算最短路的条数呢?我们只需要在dijkstra算法上稍加更改即可。例如我们a->b->c的路径长度是x,a->d->c的路径长度也是x,所以这两条路径到达c点的距离相等,我们可以很直观的直到到达c的最短路的条数是2,如果还有一条道路c->e,那么我们也很容易得知到达e的最短路径条数也是2这是一个简单的例子,我们可以很直观的看出,通过这个例子我们可原创 2021-01-22 21:04:24 · 3525 阅读 · 2 评论 -
Dijkstra 最短路还原路径
Graph 图论Dijkstra 最短路还原路径Dijkstra链接我们求最短路最常用的就是dijkstra算法,然而我们在很多时候需要打印出这条最短的路径,这时我们就要想一个办法来保存路径,这里我们借助一点点类似于并查集的思想,就是用一个path数组来存储从原点开始到达这个点的最短路径的上一步,简单来说就是我们从哪个点到的这个点,举个例子吧:假设我们已经知道 a->b->c->d 是a到d的最短路,那么d是由谁到达的呢?显然是c,那么我们就令path[d] = c;,同理path原创 2021-01-21 19:54:42 · 254 阅读 · 0 评论 -
Floyed算法(任意两点间的最短路)
Graph图论Floyed算法(任意两点间的最短路)可以处理存在负边的情况,也可以判断是否存在负环。对于最短路我们之前接触的都是单源最短路径,即起点固定,求该点开始到其他点的最短路径,但是如果我们想要求得任意两点间的最短路径,难道要对每一个点都要进行一遍dijkstra?显然比较麻烦,并且还不好存储信息,那么我们就要用到Floyed算法了。在这里我们用到一个dp数组dp[ i ][ j ]:从 i 到 j 所需要的最短距离,其实把数组的作用想明白了算法也就完成了大半,那么我们假设有一个点k,那么我们原创 2021-01-21 19:13:20 · 544 阅读 · 0 评论 -
SPFA
Graph 图论最短路(SPFA)若图中存在负权边,这时Dijkstra算法便不能再使用,而Bellman-Ford算法的复杂度又过高(O(V * E)),SPFA便能很好的优化Bellman_Ford的时间复杂度。我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路。类似于Bellman_Ford算法,我们不能像Dijkstra那样对点进行处理,前面我们已经学习了dijkstra算法来求最短路,但是dijkstra有一个很大的问题就是无法计算有负权值的图,这是因为dijkstra找到一个当前原创 2021-01-21 15:44:26 · 169 阅读 · 0 评论 -
最短路(Bellman_Ford)
Graph 图论最短路(Bellman_Ford)缺点:不能计算包含负环的图前面我们已经学习了dijkstra算法来求最短路,但是dijkstra有一个很大的问题就是无法计算有负权值的图,这是因为dijkstra找到一个当前dist最小点的时候便将该点设置为已访问,便不再处理该点,这对边权为非负数的时候适用,因为该点的权值不会再被更新(dijkstra),然而如果一个图的边带有负权值,那么该算法便不再适用,因为即使是当前dist最小的点之后还有可能会被负值所更新,所以我们就不能像dijkstra那样原创 2021-01-21 08:24:46 · 169 阅读 · 0 评论 -
最短路(Dijkstra)
Graph 图论1、最短路1、Dijkstra单源最短路(二维数组)首先我们需要这样几个数组:vis[ i ]:编号为 i 的节点是否被访问,被访问过了置为1,没有就置为0,源点的vis值置为1,因为从他本身开始走,本身肯定是被访问过;dist[ i ]:从源点开始到编号为 i 的点的最短路径,源点的dist值置为0,因为从他自己开始到他自己本身的距离就是0;map[ i ][ j ]:从 i 到 j 的道路的长度,如果从 i 到 j 没有道路,道路长度置为INF;我们的准备工作做好了我们就原创 2021-01-20 16:43:34 · 1013 阅读 · 0 评论
分享