HDU 3635
阿新 • • 發佈:2018-12-13
題意如下
n 個城市每個城市有一個編號與城市同名為 i 的龍珠
有Q 個事件
T A B 代表A城市裡所有龍珠移動到了B城市
Q A 代表詢問 A,輸出 A 龍珠所在城市,所在城市一共多少個龍珠,A一共移動了幾次。。。
簡單並查集,每次詢問一個龍珠時,父節點全部的移動加上自己的移動就是A一共移動的次數,之後合併的時候只需把 pre[a] 設為 b 同時 a 移動次數 +1, b城市龍珠數目 加上 a城市龍珠數目,a城市龍珠數目清零即可。。。
以下是 AC 程式碼
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 1e5+5; int pre[maxn],ans[maxn],num[maxn]; int t,n,m; int findd(int x) { int t; if(pre[x]==x) return x; else { t=findd(pre[x]); ans[x]+=ans[pre[x]]; pre[x]=t; return pre[x]; } } void unite(int a,int b) { int x=findd(a); int y=findd(b); if(x!=y) { pre[x]=y; ans[x]++; num[y]+=num[x]; num[x]=0; } } int main() { int x,y; int sum=0; int n,q; char a[2]; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) { pre[i]=i; num[i]=1; ans[i]=0; } printf("Case %d:\n",++sum); for(int i=1;i<=q;i++) { scanf("%s",a); if(a[0]=='T') { scanf("%d%d",&x,&y); unite(x,y); } else { scanf("%d",&x); int fx = findd(x); printf("%d %d %d\n",fx,num[pre[x]],ans[x]); } } } return 0; }