传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3172
这题就思维难度的话几乎没有……基本上只要会路径压缩和并查集基本操作就可以了(听说不用路径压缩会T)。可能最难的是用map容器吧……不是很明白的可以看一波C++ Primer Plus。
上一波C艹实现
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
using namespace std;
map <string, int> net;
const int MAXN = 100010;
int fa[MAXN];
long long Rank[MAXN];
void Init(int n){
for(int i = 0;i <= n;++i){
fa[i] = i;
Rank[i] = 1;
}
}
int Find(int x){
return fa[x] == x ? x : fa[x] = Find(fa[x]);
}
void Union(int x, int y){
int faX = Find(x), faY = Find(y);
if(faX != faY){
if(Rank[faY] < Rank[faX]){
int temp = faX;
faX = faY;
faY = temp;
} //这里按秩合并,不会改变Rank的对应关系,只是faX和faY代表的根节点交换了一下位置。
fa[faX] = faY;
Rank[faY] += Rank[faX];
}
printf("%I64d\n", Rank[faY]);
}
int main(){
//freopen("input.txt", "r", stdin);
int T;
while(~scanf("%d", &T)){
while(T--){
string Fri1, Fri2;
int n, num = 0;
scanf("%d", &n);
Init(n);
for(int i = 0;i < n;++i){
cin >> Fri1 >> Fri2;
if(!net[Fri1])
net[Fri1] = ++num;
if(!net[Fri2])
net[Fri2] = ++num;
Union(net[Fri2], net[Fri1]);
}
}
}
return 0;
}