图上问题(并查集&dfs)与单源最短路
回家胃疼了一周慢慢养病中……
先不急着做第一个题,先来回忆一下并查集的模板题。
并查集模板题
题目链接: https://www.luogu.com.cn/problem/P3367
思路:
字面意思,并查集一共有两种操作,合并和查询。
并查集是一种树形的数据结构,使用 fa[x]存节点 x 的父节点。在初始化时每个节点的父节点都是它自己。
如果要查找两个集合是否在同一个集合中,我们可以去找这两个的集合的根是否相同。根节点的父节点是自己。
带路径压缩的查找,可以在查找过程中将遇到的节点的父节点都替换为根节点。
合并操作,找到两个集合的根,将任意一个集合的根指向另一个集合的根。
启发式合并,把小集合的根指向大集合。(需要使用 size 记录树的大小)
代码:
1 |
|
P2661 信息传递
题目链接: https://www.luogu.com.cn/problem/P2661
思路:
在看过上面的并查集之后这个题应该不算问题。
代码:
1 |
|
P3916 图的遍历
题目链接: https://www.luogu.com.cn/problem/P3916
题目大意: 给出 N 个点,M 条边的有向图,对于每个点 v ,求 A(v) 表示从点 v 出发,能到达的编号最大的点。
思路:
看到这种一个点能到好几个点,然后还要找一个编号最大的点,第一个想到的应该就是 dfs 了。这里我们可以反向思维一下,如果反向建立连边的话,从序号较大的节点 dfs 如果一个节点被访问过,那么访问的起始点就是最大值了。
这里介绍两种存图方式:
邻接表存储(链式前向星):
1 | int h[N]; // 头指针数组,h[i]表示节点i的第一个邻接点在数组中的索引 |
vector 存图
1 | vector<int> p[N]; |
代码:
1 | //邻接表存图 |
1 | //vector存图 |
Cow Picnic S
题目链接: https://www.luogu.com.cn/problem/P3916
题目大意: 找到所有奶牛都可达的牧场数量。
思路:
我们可以以每头牛所在的牧场为起点,去进行 dfs,对于一个牧场遍历到一次计数器加一,找到遍历次数等于 k 的牧场。这里为了防止环路需要用到 st 数组,用完记得恢复状态。
代码:
1 |
|
P4779 【模板】单源最短路径(标准版)
题目链接: https://www.luogu.com.cn/problem/P4779
思路:
单源最短路,无负权值,是一道 dijkstra 的题。
死去的数据结构知识在攻击我。🐒🐒
首先初始化所有节点的距离为无穷大,起点距离为 0,使用优先队列维护,优先处理距离最小的节点,遍历其所有邻接边,更新节点距离。一直重复直到队列为空。
代码:
1 |
|
P1144 最短路计数
题目链接: https://www.luogu.com.cn/problem/P1144
思路:
无向图,边权都是 1,这里继续使用dijkstra。
代码:
1 |
|
P1462 通往奥格瑞玛的道路
题目链接: https://www.luogu.com.cn/problem/P1462
题目大意: 要找出满足能走通到终点的最少的钱,血量还要够,
思路:
看到最值了,考虑下二分,对于费用进行二分,对于血量用最短路。
代码:
1 |
|
- 标题: 图上问题(并查集&dfs)与单源最短路
- 作者: Lionlnuc
- 创建于 : 2026-01-27 00:00:00
- 更新于 : 2026-01-27 00:00:00
- 链接: https://lionlnuc.github.io/2026/01/27/图上问题(并查集&dfs)与单源最短路/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。