7-3 小T的疑惑 (20分)
小T是一个非常无聊的人,没事就喜欢偷听别人聊天。某天他在食堂排队时听到大一的新同学们在聊天,于是他也凑了过去。听到如下谈话:
小L : 我和小Z是同学。
小Z : 我和小H是同学。
小H : 我和小R是同学。
小B : 我和小A是同学。
小Z : 我和小Z是同学。
小T想知道,聊天的这些同学最多来自于几个不同的班级,你能帮帮他吗。
输入格式:
第一行两个整数n(1≤n≤100000),m(1≤m≤50000)。分别表示聊天中学生的数量和语句的数量。
接下来m行,每行给出一个语句,以以下形式给出:
xxx : wo he yyy shi tong xue
其中,xxx和yyy是长度不超过10的字符串,表示人名,并且xxx和yyy可能相同。
输出格式:
输出一个整数表示这些学生最多来自于多少个不同的班级。
样例1
输入样例
6 5
L : wo he Z shi tong xue
Z : wo he H shi tong xue
H : wo he R shi tong xue
B : wo he A shi tong xue
Z : wo he Z shi tong xue
输出样例
2
样例2
输入样例
6 1
L : wo he L shi tong xue
输出样例
6
//
// Created by TIGA_HUANG on 2020/10/8.
//
#include <iostream>
#include <map>
using namespace std;
int N, M;
map<string, int> mp;
//string pm[100005];
bool vis[100005];
int pre[100005];
bool dif[100005];
int find(int root) {
int x = root;
while (pre[root] != root) {
root = pre[root];
}
while (root != pre[x]) {
int t = pre[x];
pre[x] = root;
x = t;
}
return root;
}
void Union(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx != fy) {
pre[fx] = fy;
}
}
int main() {
for (int i = 0; i < 100005; ++i) {
pre[i] = i;
}
cin >> N >> M;
string a, b, t;
int k = 1;
for (int i = 0; i < M; ++i) {
cin >> a >> t >> t >> t >> b >> t >> t >> t;
if (!vis[mp[a]]) {
mp[a] = k;
vis[k++] = true;
}
if (!vis[mp[b]]) {
mp[b] = k;
vis[k++] = true;
}
Union(mp[a], mp[b]);
}
for (int i = 1; i <= k; ++i) {
dif[find(i)] = true;
}
int cnt = 0;
for (int i = 1; i <= k; ++i) {
if (dif[i])
cnt++;
}
if (k == N) {
cout << cnt << endl;
} else {
cout << N - k + cnt << endl;
}
return 0;
}