1. 程式人生 > >[luoguP2342] 疊積木(並查集)

[luoguP2342] 疊積木(並查集)

() click hide open closed include tps 技術 char

傳送門

up[i] 表示一個木塊上面有多少個

all[i] 表示整個連通塊內有多少個

那麽 一個木塊下面的木塊個數為 all[root[i]] - up[i] - 1

註意:up[i] 可以在 find 函數中維護,而 all[i] 不好維護,那麽我們只需要祖先節點的 all[i] 表示整個連通塊內木塊的數目即可

   合並時也註意維護

——代碼

技術分享
 1 #include <cstdio>
 2 #include <iostream>
 3 #define N 1000001
 4 
 5 int n;
 6 int
f[N], up[N], all[N]; 7 8 inline int read() 9 { 10 int x = 0, f = 1; 11 char ch = getchar(); 12 for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1; 13 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0; 14 return x * f; 15 } 16 17
inline int find(int x) 18 { 19 if(x ^ f[x]) 20 { 21 int fx = f[x]; 22 f[x] = find(f[x]); 23 up[x] += up[fx]; 24 } 25 return f[x]; 26 } 27 28 int main() 29 { 30 int i, x, y, fx, fy; 31 char s[1]; 32 n = read(); 33 for(i = 1; i <= n; i++) f[i] = i, all[i] = 1
; 34 for(i = 1; i <= n; i++) 35 { 36 scanf("%s", s); 37 if(s[0] == M) 38 { 39 x = read(); 40 y = read(); 41 fx = find(x); 42 fy = find(y); 43 f[fy] = fx; 44 up[fy] += all[fx]; 45 all[fx] += all[fy]; 46 } 47 else 48 { 49 x = read(); 50 fx = find(x); 51 printf("%d\n", all[fx] - up[x] - 1); 52 } 53 } 54 return 0; 55 }
View Code

[luoguP2342] 疊積木(並查集)