我已经在C ++中为Kattis问题实现了不相交集合联合。然而,我的解决方案效率低下,因为我在第一个隐藏的测试用例中得到TLA(时间限制超出)。有人能发现我的代码中的低效吗?
我基于这篇文章实现了我的代码。特别是,在设置集合的父元素时,我将较小集合的父元素的父元素设置为较大集合的父元素(在进行集合联合时)。根据上述文章,这应该与使用秩一样有效:
我基于这篇文章实现了我的代码。特别是,在设置集合的父元素时,我将较小集合的父元素的父元素设置为较大集合的父元素(在进行集合联合时)。根据上述文章,这应该与使用秩一样有效:
两种优化在时间和空间复杂度方面是等效的。因此,在实践中,您可以使用任何一种。
#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
class UnionFind {
private:
vi p;
vi size;
public:
UnionFind(int N) {
p.assign(N, 0);
for (int i = 0; i != N; ++i)
p[i] = i;
size.assign(N, 1);
}
int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
void unionSet(int i, int j) {
int x = findSet(i);
int y = findSet(j);
if (x == y)
return;
if (size[x] < size[y])
swap(x, y);
p[y] = x;
size[x] += size[y];
}
};
int main() {
int n;
int q;
cin >> n >> q;
auto set = UnionFind(n);
while (q--) {
char ch;
cin >> ch;
int x;
int y;
cin >> x >> y;
if (ch == '=') {
set.unionSet(x, y);
} else if (ch == '?') {
if (set.isSameSet(x, y))
cout << "yes" << endl;
else
cout << "no" << endl;
}
}
}
while (q--)
这样的东西,因为程序的输入和输出都对你隐藏。 - kcsquaredstd:endl
会有这么大的区别,但我应该知道得更清楚。此外,在竞赛编程中,使用头文件的“hack”实际上是一种推荐做法(但在软件工程中显然不是)。 - Bart Louwers