hdu 3635 Dragon Balls
一个城市有一个龙珠,每次两个操作,第一个操作把一个城市的龙珠移到另一个城市。
第二个操作询问第i个龙珠在哪个城市以及那个城市的size以及这个龙珠的转移次数。
用并查集维护一个联通块的size以及一个转换次数cnt。
每次合并联通块的时候把根节点的cnt++,然后在find的时候做压缩路径以及字节点cnt的更新。
#include <bits/stdc++.h> #define pb push_back #define mp make_pair #define x first #define y second #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define up rt,rt<<1,rt<<1|1 #define mem(x) memset(x,0,sizeof(x)) #define mem1(x) memset(x,-1,sizeof(x)) #define LMissher using namespace std; typedef long long ll; typedef double db; const int M = 1e4+7; const double pi = acos(-1); const int inf = 2147483647; const int mod = 1e9+7; int _,n,q,cas=1; int f[M],sz[M],cnt[M]; //维护联通块大小及转换次数 void init(){ for(int i=1;i<=n;i++) f[i]=i,sz[i]=1,cnt[i]=0; } int find(int x){//路径压缩以及子节点的转换次数更新 if(x==f[x]) return x; int tmp=f[x]; f[x]=find(f[x]); cnt[x]+=cnt[tmp]; return f[x]; } int main(){ #ifdef LMissher freopen("1.in","r",stdin); freopen("1.out","w",stdout); #endif scanf("%d",&_); while(_--){ printf("Case %d:\n",cas++); scanf("%d%d",&n,&q); init(); char op[2];int x,y; while(q--){ scanf("%s",op); if(op[0]=='T'){ scanf("%d%d",&x,&y); int fx=find(x),fy=find(y); if(fx!=fy){ sz[fy]+=sz[fx]; cnt[fx]++;//根节点的转换次数+1 f[fx]=fy; } } else{ scanf("%d",&x); int fx=find(x); printf("%d %d %d\n",fx,sz[fx],cnt[x]); } } } return 0; }

浙公网安备 33010602011771号