兩種壓縮路徑的比較數組
一,是經過用 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「