Skip to content

Commit 40508b9

Browse files
Merge pull request #2557 from buaahjy/develop
1971:解决并查集路径压缩递归可能会造成栈溢出问题
2 parents a987356 + 12fffbe commit 40508b9

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

problems/1971.寻找图中是否存在路径.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,22 @@ void init() {
3838
father[i] = i;
3939
}
4040
}
41-
// 并查集里寻根的过程
41+
// 并查集里寻根的过程,这里递归调用当题目数据过多,递归调用可能会发生栈溢出
42+
4243
int find(int u) {
4344
return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩
4445
}
4546

47+
// 使用迭代的方法可以避免栈溢出问题
48+
int find(int x) {
49+
while (x != parent[x]) {
50+
// 路径压缩,直接将x链接到其祖先节点,减少树的高度
51+
parent[x] = parent[parent[x]];
52+
x = parent[x];
53+
}
54+
return x;
55+
}
56+
4657
// 判断 u 和 v是否找到同一个根
4758
bool isSame(int u, int v) {
4859
u = find(u);
@@ -75,6 +86,8 @@ void join(int u, int v) {
7586
7687
此时我们就可以直接套用并查集模板。
7788
89+
本题在join函数调用find函数时如果是递归调用会发生栈溢出提示,建议使用迭代方法
90+
7891
使用 join(int u, int v)将每条边加入到并查集。
7992
8093
最后 isSame(int u, int v) 判断是否是同一个根 就可以了。
@@ -93,8 +106,13 @@ private:
93106
}
94107
}
95108
// 并查集里寻根的过程
96-
int find(int u) {
97-
return u == father[u] ? u : father[u] = find(father[u]);
109+
int find(int x) {
110+
while (x != parent[x]) {
111+
// 路径压缩,直接将x链接到其祖先节点,减少树的高度
112+
parent[x] = parent[parent[x]];
113+
x = parent[x];
114+
}
115+
return x;
98116
}
99117
100118
// 判断 u 和 v是否找到同一个根

0 commit comments

Comments
 (0)