并查集
写法1:
查找时间复杂度: O ( 1 ) O(1) O(1)
int findx(int x) {
return Set[x];
}
归并时间复杂度: O ( n ) O(n) O(n)
void merge(int a,int b) {
mi = min(a,b);
ma = max(a,b);
for (int i=1;i<=n;i++) {
if (Set[i] == ma) {
Set[i] = mi;
}
}
}
优化(其实算不上优化) 写法2:
查找时间复杂度(最坏情况): O ( n ) O(n) O(n)
int findx(int x) {
while (Set[x] != x) {
x = Set[x];
}
return x;
}
归并时间复杂度: O ( 1 ) O(1) O(1)
void merge(int a,int b) {
Set[b] = a;
}
优化(路径压缩)
思想
找到路径上的所有结点,利用递归记忆化将其归为根结点
查找时间复杂度: O ( n log n ) O(n\log{n}) O(nlogn)
int findx(int x) {
if (findx(x) != x) {
Set[x] = findx(Set[x]);
}
return Set[x];
}
归并时间复杂度: O ( 1 ) O(1) O(1)
void merge(int a,int b) {
Set[a] = b;
}