朋友
朋友
题目背景
小明在 A 公司工作,小红在 B 公司工作。
题目描述
这两个公司的员工有一个特点:一个公司的员工都是同性。
A 公司有 \(N\) 名员工,其中有 \(P\) 对朋友关系。B 公司有 \(M\) 名员工,其中有 \(Q\) 对朋友关系。朋友的朋友一定还是朋友。
每对朋友关系用两个整数 \((X_i,Y_i)\) 组成,表示朋友的编号分别为 \(X_i,Y_i\)。男人的编号是正数,女人的编号是负数。小明的编号是 \(1\),小红的编号是 \(-1\)。
大家都知道,小明和小红是朋友,那么,请你写一个程序求出两公司之间,通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。
输入格式
输入的第一行,包含 \(4\) 个空格隔开的正整数 \(N,M,P,Q\)。
之后 \(P\) 行,每行两个正整数 \(X_i,Y_i\)。
之后 \(Q\) 行,每行两个负整数 \(X_i,Y_i\)。
输出格式
输出一行一个正整数,表示通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。
样例 #1
样例输入 #1
4 3 4 2
1 1
1 2
2 3
1 3
-1 -2
-3 -3
样例输出 #1
2
提示
对于 \(30 \%\) 的数据,\(N,M \le 100\),\(P,Q \le 200\);
对于 \(80 \%\) 的数据,\(N,M \le 4 \times 10^3\),\(P,Q \le 10^4\);
对于 \(100 \%\) 的数据,\(N,M \le 10^4\),\(P,Q \le 2 \times 10^4\)。
分析
这道题看似通过建立男女两个并查集,然后再遍历一下个公司员工看他们是否与1有关系,但要注意:女生是负数,所以输入要记得abs,其次,是查找操作,也要对1进行查找,不能直接等于1.
代码实现
#include <bits/stdc++.h>
using namespace std;
const int N = 30000;
int s[N];
int height[N];
void init_set() {
for (int i = 1; i <= N; i++) {
s[i] = i;
height[i] = 0;
}
}
int find_set(int x) {
if (x != s[x]) s[x] = find_set(s[x]);
return s[x];
}
void merge_set(int x, int y) {
x = find_set(x);
y = find_set(y);
if (x == y) return;
if (height[x] == height[y]) {
height[x]++;
}
if (height[x] < height[y]) {
s[x] = y;
} else {
s[y] = x;
}
}
int main() {
int n, m, p, q, nn = 0, mm = 0;
cin >> n >> m >> p >> q;
init_set();
while (p--) {
int a, b;
cin >> a >> b;
merge_set(a, b);
}
for (int i = 1; i <= n; i++) {
if (find_set(i) == find_set(1)) nn++;
}
init_set();
while (q--) {
int a, b;
cin >> a >> b;
a = abs(a);
b = abs(b);
merge_set(a, b);
}
for (int i = 1; i <= m; i++) {
if (find_set(i) == find_set(1)) mm++;
}
cout << min(nn, mm);
return 0;
}

浙公网安备 33010602011771号