题解: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;正解
就是并查集板子外加连边时顺带记录时间最大值
最后检查所有点的祖先节点是否一致,不一致输出
:
#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 longusing 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,yint 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/相关文章智能推荐
1
题解:P5690 [CSP-S 2019 江西] 日期
题解题解:P5690 [CSP-S 2019 江西] 日期
2
题解:P1360 [USACO07MAR] Gold Balanced Lineup G
题解题解:P1360 [USACO07MAR] Gold Balanced Lineup G
3
一些冷门但好用的STL容器
OISTL真的很好用
4
关于我的OI代码缺省源
OI以后懒得写了直接复制
5
从0写软件-Win32应用代码模板
C++有点像大份
随机文章随机推荐











