两种压缩路径的比较数组
一,是经过用 rank 数组,记录树的深度直接比较ide
二,直接让全部点指向 根spa
二 的深度始终为 1,code
一 的深度只有当两个集合的深度不同时才不会增长blog
因此,应该说,二 路径是不彻底压缩,或者说压缩的还不够string
一,it
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #define M(a,w) memset(a,w,sizeof(a)); #define N (int)1e6+6 int pa[N], max[N], num[N], rank[N]; int maxer(int x, int y) { return x > y ? x : y; } int find(int x) { while (pa[x] != -1) x = pa[x]; return x; } void join(int x, int y) { x = find(x); y = find(y); if (x == y) return; if (rank[x] > rank[y]) { pa[y] = x; num[x] += num[y]; max[x] = maxer(max[x], max[y]); } else if (pa[x] < pa[y]) { pa[y] = x; num[y] += num[x]; max[y] = maxer(max[x], max[y]); } else { pa[y] = x; num[x] += num[y]; // 累加 max[x] = maxer(max[x], max[y]); // 找到目前编号 rank[x]++; } } int main(void) { int n, m; char s[10]; while (scanf("%d%d", &n, &m) != EOF) { M(pa, -1); M(rank, 0); for (int i = 1; i <= n; i++) { max[i] = i; num[i] = 1; } int sum = n, x, y; while (m--) { scanf(" %s", s); if (s[0] == 'u') { scanf("%d%d", &x, &y); if (find(x) != find(y)) { join(x, y); sum--; } } if (s[0] == 's'&&s[1] == 'a') { scanf("%d%d", &x, &y); if (find(x) == find(y)) puts("1"); else puts("0"); } if (s[0] == 'n') { scanf("%d", &x); printf("%d\n", num[find(x)]); } if (s[0] == 'm') { scanf("%d", &x); printf("%d\n", max[find(x)]); } if (s[1] == 'e') { printf("%d\n", sum); } } } }
二,io
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #define M(a,w) memset(a,w,sizeof(a)); #define N (int)1e6+6 int pa[N], max[N], num[N]; int maxer(int x, int y) { return x > y ? x : y; } int find(int x) { int p = x; while (x != pa[x]) x = pa[x]; while (p != x) // 让全部点都直接指向 根 { int t = pa[p]; pa[p] = x; p = t; } return x; } void join(int x, int y) { x = find(x); y = find(y); if (x == y) return; // 因此最后都是两层的就不用比较了吗 pa[x] = y; max[y] = maxer(max[x], max[y]); num[y] += num[x]; } int main(void) { int n, m; char s[10]; while (scanf("%d%d", &n, &m) != EOF) { for (int i = 1; i <= n; i++) { pa[i] = i; max[i] = i; num[i] = 1; } int sum = n, x, y; while (m--) { scanf(" %s", s); if (s[0] == 'u') { scanf("%d%d", &x, &y); if (find(x) != find(y)) { join(x, y); sum--; } } if (s[0] == 's'&&s[1] == 'a') { scanf("%d%d", &x, &y); if (find(x) == find(y)) puts("1"); else puts("0"); } if (s[0] == 'n') { scanf("%d", &x); printf("%d\n", num[find(x)]); } if (s[0] == 'm') { scanf("%d", &x); printf("%d\n", max[find(x)]); } if (s[1] == 'e') { printf("%d\n", sum); } } } }
======== ======= ======= ======= ====== ===== ===== === == =class
.个人朋友,我还有一点疑虑——你是否是由于太懦弱了,才这样以炫耀本身的痛苦来做为本身的骄傲? -- 《基督山伯爵》集合
My friend, I have a little doubt -- are you too weak to show off your pain as a source of pride? -- ”The count of monte cristo“