交友网络。有多个数据,每组数据中给出n个交友网络,每个交友网络给出m条交友关系,求该交友网络中有几个人。
用并查集来做,思想是用带权并查集的思想,把每条关系的权值看成1,每多一个人就在这个交友关系的根节点上加1。这题需要注意的是,它的测试数据量很大,cin、cout用太多会超时,所以在输出时要用printf。还有输入的是人名,所以可以用map建立一个映射。
#include <cstdio>
#include <string>
#include <map>
#include <iostream>
using namespace std;
const int MAXN = 100005 ;
int fa[MAXN] , num[MAXN] ;
map <string , int> fri ;
int find(int x) {
return (fa[x] == x)? x : fa[x] = find(fa[x]) ;
}
void Union(int x , int y) {
int fx , fy ;
fx = find(x) ; fy = find(y) ;
if (fx == fy) {
printf("%d\n" , num[fx]) ;
return ;
}
else {
fa[fy] = fx ;
num[fx] += num[fy] ;
printf("%d\n" , num[fx]) ;
return ;
}
}
int main() {
//freopen("in.txt" , "r" , stdin) ;
int n ;
while (cin >> n) {
while (n--) {
fri.clear() ;
int m , number = 1 ;
cin >> m ;
if (m == 0) {
cout << "0" << endl ;
continue ;
}
while (m --) {
string a , b ;
cin >> a >> b ;
if (!fri[a]) {
fri[a] = number ++ ;
fa[fri[a]] = fri[a] ;
num[fri[a]] = 1 ;
}
if (!fri[b]) {
fri[b] = number ++ ;
fa[fri[b]] = fri[b] ;
num[fri[b]] = 1 ;
}
Union(fri[a] , fri[b]) ;
}
}
}
return 0 ;
}