#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int par[int(3e4 + 5)] , cnt[int(3e4 + 5)] , dis[int(3e4 + 5)];
//cnt[i]表示i所在点的大小,dis[i]表示i离最上面节点的距离(个数)
int Find(int n) {
if(par[n] == n) return n;
int temp = Find(par[n]); //先算出n的父节点的dis
cout<<"temp:"<<temp<<" par["<<n<<"]:"<<par[n]<<endl;
dis[n] += dis[par[n]];
cout<<"dis["<<n<<"]:"<<dis[n]<<endl;
par[n] = temp; //路径压缩
cout<<"par["<<n<<"]:"<<par[n]<<endl;
return temp;
}
void Union(int u , int v) {
int fu = Find(u) , fv = Find(v);
if(fu == fv)
return ;
cout<<"fu:"<<fu<<" fv:"<<fv<<endl;
par[fv] = fu;
cout<<"par["<<fv<<"]"<<par[fv]<<endl;
dis[fv] = cnt[fu]; //Find函数中dis[fv]并没有回溯增加过
cout<<"cnt["<<fu<<"]"<<cnt[fu]<<" dis["<<fv<<"]"<<dis[fv]<<endl;
cnt[fu] += cnt[fv]; //总个数相加
cout<<"cnt["<<fu<<"]"<<cnt[fu]<<endl;
}
int main()
{
int n , u , v;
char q[3];
while(cin>>n) {
memset(dis , 0 , sizeof(dis));
for(int i = 1 ; i <= 3e4 ; ++i) {
cnt[i] = 1;
par[i] = i;
}
for(int i = 0 ; i < n ; ++i) {
cin>>q;
if(q[0] == 'M') {
cin>>u>>v;
Union(u , v);
}
else {
cin>>u;
int x = Find(u); //回溯累加一次
cout<< "cnt["<<x<<"]-dis["<<u<<"]-1:"<<cnt[x] - dis[u] - 1<<endl;
}
}
}
return 0;
}
//
POJ - 1988:并查集(带权)
最新推荐文章于 2019-04-29 22:56:12 发布