写并查集出现段错误?
在疯狂百度之后,我总结了自己专用的并查集模板,但是交代码时,出现了段错误,我前删后删,终于找到了该死的bug!
下面是我之前的并查集模板。
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 1000005;
int p[maxn], r[maxn], id[maxn];
int l[maxn];
int init(int n){
for(int i = 1; i <= n; i++){
p[i] = i;
r[i] = 1;
id[i] = i;
}
}
int find(int x){
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
bool connected(int x, int y){
return find(x) == find(y);
}
void Union(int x, int y){
x = find(x);
y = find(y);
if(x == y) return;
if(r[x] < r[y]) p[x] = y;
else if(r[x] > r[y]) p[y] = x;
else {
p[x] = y;
r[y]++;
}
}
上面的代码在我们本地的编辑器上运行不会有任何问题。
但是当我们在牛客上交上一发时,结果却是:段错误
为什么会这样呢?
从牛客上给我们的提示上,我们可以看到
是的,根据这个提示,是个人都会想我的数组有没有越界,递归层数是不是太多了嗷?然而,经过我反反复复的检查,我并没有发现我的数组和递归有任何毛病。于是我采用了删代码法,很快,我就找到了这个bug,其实就是因为我们的init函数有问题,下面我们仔细看一看这个init函数:
int init(int n){
for(int i = 1; i <= n; i++){
p[i] = i;
r[i] = 1;
id[i] = i;
}
}
一眼看上去,好像没有什么问题嗷。现在给你2分钟时间,看看能不能找到bug。
—————————————2分钟后—————————————
看到这里,我想你应该已经知道了,我们只需要将int改为void即可,因为我们的函数没有返回值,所以必须要用void,改完之后,我们发现段错误就消失了。
总结,以后一定要注意函数的返回值类型问题!