某个比赛现场有来自不同学校的N
名学生,给出M
对“两人同属一所学校”的关系, 请推断学校数量,并找出人数最多的学校。
输入格式:
第一行是一个在[2, 1000]
范围的整数N
,
接下来N
行,每行是一个在现场的学生的姓名,每个姓名仅由字母组成,长度不超过30
。
接下来一行是非负整数M
,表示有M
对关系;
然后是M
行,每行是用空格间隔的两个人名,表示同属一所学校。
输出格式:
在一行内分别输出学校的数量以及人数最多学校的人数,用一个空格分隔。
输入样例:
8
Bill
Ellen
Ann
Chris
Daisy
Flin
Henry
Grace
5
Ann Chris
Ellen Chris
Daisy Flin
Henry Ellen
Grace Flin
输出样例:
3 4
#include<iostream>
#include<set>
#include<map>
using namespace std;
int N, M;
string name[1001];
int parent[1001];
set<string> s[1001];
map<string, int> m;
int findRoot(int k){
if(parent[k] == -1) return k;
int rk = k, tmp;
//找根
while(parent[rk] > 0)
rk = parent[rk];
//使其余节点与根直接相连
for(int i = k; i != rk; i = tmp){
tmp = parent[i];
parent[i] = rk;
}
return rk;
}
void unionMates(int r1, int r2){
if(r1 == r2) return ;
else if(parent[r1] < parent[r2]){
parent[r1] += parent[r2];
parent[r2] = r1;
s[r1].insert(s[r2].begin(), s[r2].end());
s[r2].clear();
}else{
parent[r2] += parent[r1];
parent[r1] = r2;
s[r2].insert(s[r1].begin(), s[r1].end());
s[r1].clear();
}
}
int main(){
cin >> N;
for(int i = 1; i <= N; i++){
cin >> name[i];
parent[i] = -1;
m[name[i]] = i;
s[i].insert(name[i]);
}
cin >> M;
for(int i = 0; i < M; i++){
string n1, n2;
cin >> n1 >> n2;
int n1Root = findRoot(m[n1]);
int n2Root = findRoot(m[n2]);
unionMates(n1Root, n2Root);
}
int max = 0, cnt = 0;
for(int i = 1; i <= N; i++){
if(s[i].size() > 0){
cnt++;
if(s[i].size() > max) max = s[i].size();
}
}
cout << cnt << ' ' << max;
return 0;
}