hdu 3635 Dragon Balls 并查集应用记录每个点的转移次数

题意:

有n个龙珠,分别存放在编号为1-n的城市里面。然后进行如下操作,T,a,b将a龙珠所在城市的所有龙珠都转移到b龙珠所在的城市,Q,a输出a龙珠所在的城市,以及该城市一共有多少个龙珠,同时输出该龙珠被转移的次数,

思路:

并查集,前两项比较好像,后一项记录转移次数,我们只需要记录每一个点到达父节点所需的转移次数no[i]然后再路径压缩的时候求一个和,压缩完成后该点的no值就是该点的转移次数了。

View Code
#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll __int64

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define M 30007

#define N 10007



using namespace std;



const int inf = 100000007;

const int mod = 1000000007;



int f[N];

int no[N],tim[N];

int n,m;



void init()

{

    for (int i = 0; i <= n; ++i)

    {

        f[i] = i;

        no[i] = 1;

        tim[i] = 0;

    }

}

int find(int x)

{

    if (f[x] != x)

    {

        int fa = find(f[x]);

        tim[x] += tim[f[x]];

        f[x] = fa;

    }

    return f[x];

}

void Union(int x,int y)

{

    x = find(x);

    y = find(y);

    if (x != y)

    {

        f[x] = y;

        no[y] += no[x];

        tim[x]++;

    }

}

int main()

{

//    Read();

    int T;

    char op[2];

    int cas = 1;

    scanf("%d",&T);

    while (T--)

    {

        printf("Case %d:\n",cas++);



        scanf("%d%d",&n,&m);

        init();

        while (m--)

        {

            scanf("%s",op);

            int x,y;

            if (op[0] == 'T')

            {

                scanf("%d%d",&x,&y);

                Union(x,y);

            }

            else

            {

                scanf("%d",&x);

                int rt = find(x);

                printf("%d %d %d\n",rt,no[rt],tim[x]);

            }

        }

    }

    return 0;

}

 

 

你可能感兴趣的:(drag)