很简单的并查集,只不过不能用fa数组去储存了,要开一个map<string,string>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
map<string,string>w;
string find1(string x){
auto j=w.find(x);
if(j->second==x)return x;
else{
j->second=find1(j->second);
return j->second;
}
}
void unionn(string a,string b){
string a_=find1(a);
string b_=find1(b);
auto j=w.find(a);
j->second=b_;
}
void solve(){
string t;
cin>>t;
// 数据输入有点小技巧
while(t[0]!='$'){
if(t[0]=='#'){
t=t.substr(1,t.size());
w.insert({t,t});
string e;
cin>>e;
while(e[0]=='+'){
e=e.substr(1,e.size());
if(!w.count(e))w.insert({e,e});
unionn(e,t);
cin>>e;
}
t=e;
}else if(t[0]=='?'){
// 切记不能直接输出他的最早祖先,会有三个wa,为什么呢?
// #QUARRY
// +JIMMEY
// #PARENT
// +QUARRY
// ?JIMMEY
// $
// 看这组数据JIMMEY的刚开始祖先是QUARRY,后来QUARRY的祖先变成了PARENT
// 因为要求最早的祖先所以JIMMEY的最早祖先是PARENT但是在过程中并没有用unionn去
// 更新祖先所以会输出JIMMEY的最早祖先是QUARRY,所以我们要用find1去找最早祖先并更新
t=t.substr(1,t.size());
find1(t);//关键代码
auto j=w.find(t);
cout<<j->first<<" "<<j->second<<endl;
cin>>t;
}
}
return ;
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _;
//cin>>_;
_=1;
while(_--){
solve();
}
return 0;
}