gpt4 book ai didi

c++ - Union-find 方法性能,迭代与递归

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:52:07 24 4
gpt4 key购买 nike

问题本质上是我发现 union-find 方法的递归版本比迭代版本更快。

// the union find method - recursive
int find(int k) {
if(f[k] != k) f[k] = find(f[k]);
return f[k];
}

// the union find method - iterative
int find(int k){
while(f[k] != k) k = f[k];
return f[k];
}

问题的上下文在这里:good or bad balance .

问题表明我们有平衡,但我们不知道它是好是坏。我们有两种不同重量的元素,同一种元素具有相同的重量。我们将所有项目索引为 1,2,3..n。我们随机挑选其中两个并称量天平。每个称量结果用x,u,v的形式表示,其中x为位指示符,0表示平衡,1表示不平衡,u和v为两项指标。

如果天平不好,就会出现矛盾,比如我们称重的结果是这样的:

0 1 2
1 1 2

item 1和item 2在两个measure中有不同的关系,所以平衡不好。我需要编写一个程序来告诉最早可以确定余额是坏的还是余额是好的。

基本上,这是经典 union 查找问题的变体。我希望迭代 union-find 方法可以带来更好的性能,但是当递归版本被接受时我得到了 Time Limit Exceeded 。我想问这是为什么???

这是我的算法的完整版本。

#include <iostream>
#include <vector>

using namespace std;

#define N 10009

int n, m;
int x,u,v;
vector<int> f(2*N+1,0);

// iterative
int find(int k) {
if(k!=f[k]) f[k] = find(f[k]);
return f[k];
}

// recursive
// int find(int k) {
// while(k!=f[k]) k=f[k];
// return f[k];
// }

int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T; // T is number of test cases
cin >> T;
while(T--){
// n is number of items, m is number of measurements
cin >> n >> m;
f.resize(2*n+1);
for(int i = 0 ; i < 2*n+1; ++i){
f[i] =i;
}

bool flag = false;
int ans = 0;
int r1, r2;
for(int i = 1 ; i <= m ; ++i){
// x is weighing result, u and v are item id.
cin >> x >> u >> v;
if(flag) continue;
if(x == 0) {
// two items are balance
if(find(u) == find(v+n) || find(v) == find(u+n)){
flag = true;
ans = i;
continue;
}
r1 = find(u); r2 = find(v);f[r2] = r1;
r1 = find(u+n); r2= find(v+n); f[r2] = r1;
} else {
// two items are imbalance
if(find(u) == find(v)){
flag = true;
ans = i;
continue;
}
r1 = find(u); r2= find(v+n);f[r2]=r1;
r1 = find(v); r2 = find(u+n);f[r2]=r1;
}
}
if(flag){
cout << "sad" << endl;
cout << ans << endl;
} else
cout << "great" << endl;
}


return 0;
}

示例测试用例是

2
4 5
0 1 3
1 2 4
0 1 4
0 3 4
0 1 2
2 2
0 1 2
1 1 2

最佳答案

递归和迭代版本做的事情不同。递归版本将用结果更新 f[k],因此在随后的具有相同 k 值的调用中,最多可以通过一次递归调用找到答案。如果已经找到其中一个中间值,即使在初始调用时也可以观察到这种效果。

迭代版本不会更新 f 数组,因此后续调用必须执行完整循环,直到找到答案。

也有可能优化器可以内联一些递归,因此它不像最初看起来那样递归。

关于c++ - Union-find 方法性能,迭代与递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47405409/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com