1. 程式人生 > >HDU 3635 Dragon Balls(帶權並查集)

HDU 3635 Dragon Balls(帶權並查集)

clas pos 水題 ont span popu post join --

題目地址:

pid=3635">HDU 3635

加權並查集水題。

用num數組維護該城市有多少龍珠,用times數組維護每一個龍珠運輸了多少次。num數組在合並的時候維護。times數組因為每一個都不一樣。所以要在找根的時候遞歸來所有維護。

終於,x龍珠所在的城市就是x節點所在的根,x結點所在的跟的num數組值是該城市的龍珠數。times[x]為該龍珠運輸了多少次。

代碼例如以下:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

using namespace std;
#define LL long long
int bin[20000], num[20000], times[20000];
int find1(int x)
{
    int y;
    if(bin[x]!=x)
    {
        y=bin[x];
        bin[x]=find1(bin[x]);
        times[x]+=times[y];
    }
    return bin[x];
}
void join(int x, int y)
{
    int f1=find1(x);
    int f2=find1(y);
    if(f1!=f2)
    {
        bin[f1]=f2;
        num[f2]+=num[f1];
        times[f1]++;
    }
}
int main()
{
    int t, nn=0, n, m, i, a, b, f;
    char c;
    scanf("%d",&t);
    while(t--)
    {
        nn++;
        scanf("%d%d",&n,&m);
        for(i=1; i<=n; i++)
        {
            bin[i]=i;
            num[i]=1;
            times[i]=0;
        }
        printf("Case %d:\n",nn);
        while(m--)
        {
            getchar();
            scanf("%c",&c);
            if(c=='T')
            {
                scanf("%d%d",&a,&b);
                join(a,b);
            }
            else
            {
                scanf("%d",&a);
                f=find1(a);
                printf("%d %d %d\n",f,num[f],times[a]);
            }
        }
    }
    return 0;
}


HDU 3635 Dragon Balls(帶權並查集)