题解:P1111 修复公路

475 字
2 分钟
题解:P1111 修复公路

并查集板子题,如果你这题AC了,那题目标签带并查集的黄题基本都是多倍经验

并查集#

以我个人的理解<记录每一个点的祖先节点>,如果两个点的祖先节点一致,则说明两点间相互连通;否则,说明两点在不同的连通图中

实现#

首先需要设定一个一位数组来存储每个节点的祖先节点,我一般习惯把这个数组命名为fa

初始化#

fa数组的每一位设为他的下标,对于vector的快捷STL实现可以看先前文档的底部

查询祖先节点#

定义int find(u)函数用于查询祖先节点,如果fa[u]==u,直接返回u即可

否则,fa[u]=find(fa[u])来更新和查询祖先节点,最后返回fa[u]

代码实现:

int find(u){
if(fa[u]!=u) fa[u]=find(fa[u]);
return fa[u];
}

设定祖先节点#

对于添加一条新边,只需将边的任意一个端点的祖先节点的祖先设定为另一个端点的祖先节点即可

知道听起来很绕,所以直接放代码实现吧:

std::cin>>u>>v;//输入边的两个端点
int fu=find(u),fv=find(v);
if(fu!=fv) fa[fu]=fv;

正解#

就是并查集板子外加连边时顺带记录时间最大值

最后检查所有点的祖先节点是否一致,不一致输出1-1

ACcodeAC code:#

#include<iostream>
#include<string>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<functional>
#include<utility>
#include<algorithm>
#include<cmath>
#include<climits>
#include<tuple>
#include<numeric>
#include<any>
#include<bitset>
#define int long long
using namespace std;
const int N = 1e3 + 10;
int n, m, tx, ty, tt, ans;
vector<int> fa;
multiset<tuple<int, int, int>> mul;//t,x,y
int find(int u) {
if (fa[u] != u) fa[u] = find(fa[u]);
return fa[u];
}
signed main() {
cin.tie(nullptr)->ios::sync_with_stdio(false);
cin >> n >> m;
fa.resize(n + 10);
iota(fa.begin(), fa.end(), 0);
while (m--) cin >> tx >> ty >> tt, mul.insert(make_tuple(tt, tx, ty));
while (!mul.empty()) {
auto [t, x, y] = *(mul.begin());
mul.erase(mul.begin());
int fx = find(x), fy = find(y);
if (fx != fy) fa[fx] = fy, ans = max(ans, t);
}
for (int i = 1;i <= n;i++)
if (find(i) != find(1)) {
cout << -1;
return 0;
}
cout << ans;
return 0;
}

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
题解:P1111 修复公路
https://azx.xn--0iv.gay/posts/solution-p1111/
作者
WanFoxAZX
发布于
2026-08-28
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
WanFoxAZX
Hello, I'm AZX.
公告
Welcome!
分类
标签
最新动态

还没有发布动态

更多动态
站点统计
文章
10
动态
0
分类
6
标签
5
总字数
2,549
运行时长
0
最后活动
0 天前
站点信息
构建平台
Netlify CI
博客版本
Firefly v6.15.5
文章许可
CC BY-NC-SA 4.0