是map+并查集的做法。
直接交85pts,subtask#3有几个TLE,看了题解说开O2能过,但是我开了就全MLE了……
#include<iostream>
#include<map>
using namespace std;
const int N = 1e5+10;
map<string,int> mp;
int a[N],p[N];
pair<int,int> same[N],dif[N];
int n,m,q;
int find(int x){
if(x != p[x]) return p[x] = find(p[x]);
}
void solve(){
int t = 0,k1 = 0,k2 = 0;
scanf("%d",&n);
for(int i = 1; i < N; i++) p[i] = i;
for(int i = 1; i <= n; i++){
string s1,s2;
cin >> s1 >> s2;
if(!mp[s1]) mp[s1] = ++t;
if(!mp[s2]) mp[s2] = ++t;
int a = mp[s1],b = mp[s2];
same[++k1] = {a,b};
}
scanf("%d",&m);
for(int i = 1; i <= m; i++){
string s1,s2;
cin >> s1 >> s2;
if(!mp[s1]) mp[s1] = ++t;
if(!mp[s2]) mp[s2] = ++t;
int a = mp[s1],b = mp[s2];
dif[++k2] = {a,b};
}
scanf("%d",&q);
for(int i = 1; i <= q; i++){
string s1,s2,s3;
cin >> s1 >> s2 >> s3;
if(!mp[s1]) mp[s1] = ++t;
if(!mp[s2]) mp[s2] = ++t;
if(!mp[s3]) mp[s3] = ++t;
int a = mp[s1],b = mp[s2],c = mp[s3];
if(find(a) != find(b)) p[find(a)] = find(b);
if(find(b) != find(c)) p[find(b)] = find(c);
}
int ans = 0;
for(int i = 1; i <= k1; i++){
int a = same[i].first,b = same[i].second;
if(find(a) != find(b)) ans++;
}
for(int i = 1; i <= k2; i++){
int a = dif[i].first,b = dif[i].second;
if(find(a) == find(b)) ans++;
}
printf("%d\n",ans);
}
int main(){
int t = 1;
// scanf("%d",&t);
while(t--) solve();
return 0;
}