分析:
每次给出两个人存在关系,就是求同一集合内元素的个数。
很郁闷的事情,我用先前并查集的模板的时候总会WA在第二个测试点,我自己写的时候用的是,遍历每一个点,判断父亲结点是否相同,相同就加,不知道为什么
WA。
后面用了别人的写法,在合并的时候就统计每个父亲结点同一个集合元素的个数。
#include<iostream>
#include<cstdio>
#include<map>
#define sf scanf
#define pf printf
#define maxn 100010
using namespace std;
typedef long long ll;
ll T,m,Rank[maxn],pa[maxn],cnt,ans,num[maxn];
map<string,ll> mp;
string s1,s2;
void init(){
for(int i=0;i<=maxn;i++){
Rank[i]=1;
pa[i]=i;
num[i]=1;
}
}
ll find_set(ll x){
if(x!=pa[x]){
pa[x]=find_set(pa[x]);
}
return pa[x];
}
void union_set(ll x, ll y){
x=find_set(x);
y=find_set(y);
if(x==y){
return ;
}
pa[y]=x;
num[x]+=num[y];
/* if(Rank[x]>Rank[y]) {
pa[y]=x;
}
else{
pa[x]=y;
if(Rank[x]==Rank[y]){
Rank[y]++;
}
} */
}
/*
ll solve(ll tmp){
ans=0;
for(int i=0;i<=cnt;i++){
if(pa[i]==tmp){
//cout<<"i= "<<i<<endl;
ans++;
}
}
return ans;
} */
int main(){
sf("%lld",&T);
while(T--){
init();
cnt=0;
sf("%lld",&m);
for(int i=0;i<m;i++){
cin>>s1>>s2;
if(mp.find(s1)==mp.end()) mp[s1]=++cnt;
if(mp.find(s2)==mp.end()) mp[s2]=++cnt;
union_set(mp[s1],mp[s2]);
ll tmp=find_set(mp[s1]);
cout<<num[tmp]<<endl;
// cout<<"父结点是:"<<tmp<<endl;
// pf("%lld\n",solve(tmp));
}
}
return 0;
}