Cube Stacking 【POJ - 1988】【並查集(帶權並查集)】
阿新 • • 發佈:2018-12-25
題目連結
題意就是給你一串箱子,題目中沒有給出箱子的數量,問你經過一系列移動之後,某個ID箱子下面有幾個箱子,然後移動是把這一整列都按照原來的順序放在另一列的頂端上去。
所以,我想到了用並查集來寫,對於一個箱子,我們把它放到另一列箱子的上面,我們可以維護下這一列有多少箱子,以及這個箱子之上有多少箱子(不包括自己的),然後,我們所要求的其下的箱子的個數就是“總的這一列的箱子數-其上的箱子數-1”,多減一個“1”是為了減去自己。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define efs 1e-7 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 3e4 + 7; int N, root[maxN], sum[maxN], num[maxN]; //sum是此時的值,num是總和 int fid(int x) { if(x == root[x]) return x; int tmp = root[x]; root[x] = fid(root[x]); sum[x] = sum[x] + sum[tmp]; return root[x]; } void mix(int x, int y) { int u = fid(x), v = fid(y); if(u != v) { sum[v] = num[u]; root[v] = u; num[u] += num[v]; } } void init() { for(int i=0; i<maxN; i++) { root[i] = i; sum[i] = 0; num[i] = 1; } } int main() { while(scanf("%d", &N)!=EOF) { init(); while(N--) { char op[3]; int x, y; scanf("%s", op); if(op[0] == 'M') { scanf("%d%d", &x, &y); mix(x, y); } else { scanf("%d", &x); printf("%d\n", num[fid(x)] - sum[x] - 1); } } } return 0; } /* 4 M 1 6 M 2 4 M 2 6 C 1 ans = 1;(Accept) */