hdu3635Dragon Balls 并查集

来源:互联网 发布:mac qq截图保存位置 编辑:程序博客网 时间:2024/04/28 16:23
//n个龙珠,在n个城市
//T a b 将包含a的所有龙珠移到b处
//Q a
//龙珠a在哪个城市,这个城市有多少龙珠 , 龙珠a移动了多少次
//并查集记录所有龙珠
//对于移动的次数在find更新的时候优化一下就行
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std ;
const int maxn = 10010 ;
int F[maxn] ;
int sum[maxn] ;
int time[maxn] ;
int find(int x)
{
   int r = x ;
   int sum_b = 0 ;
   int res = 0 ;
   while(r!=F[r])
   {
       sum_b += time[r] ;
       r = F[r] ;
   }
   int i = x ;
   while(F[i] != r)
   {
       int j = F[i] ;
       F[i] = r ;
       int t = time[i] ;
       time[i] = sum_b - res ;
       res += t;
       i = j ;
   }
   return r ;
   /*if(x == F[x])return F[x] ;
   int t = F[x] ;
   F[x] = find(F[x]) ;
   time[x] += time[t] ;
   return  F[x];*/
}
void join(int a, int b)
{
    int fx = find(a) ;
    int fy = find(b) ;
    if(fx != fy)
    {
        time[fx] = 1 ;
        F[fx] = fy ;
        sum[fy] += sum[fx] ;
        sum[fx] = 0 ;
    }
}
int main()
{
    //freopen("in.txt" ,"r" , stdin) ;
    int T ;int cas = 0 ;
    scanf("%d" , &T) ;
    while(T--)
    {
        int N , Q ;
        scanf("%d%d" , &N , &Q) ;
        for(int i = 1;i <= N;i++)
        F[i] = i ,sum[i] = 1;
        memset(time , 0 , sizeof(time)) ;
        printf("Case %d:\n" ,++cas) ;
        char ch  ;int a ,b ;
        for(int i = 1;i <= Q ;i++)
        {
            scanf("%c%c" , &ch,&ch ) ;
            if(ch == 'T')
            {
                scanf("%d%d" , &a , &b) ;
                join(a , b) ;
            }
            else if(ch == 'Q')
            {
                scanf("%d" , &a) ;
                int fx = find(a) ;
                printf("%d %d %d\n" ,fx , sum[fx] , time[a]) ;
            }
        }
    }
    return  0 ;
}



































































0 0