题目描述
题目分析
涉及到元素分组问题,考虑使用并查集。由于同一个公司的员工都是同性,可以构造一个并查集,小明的朋友圈人数为,小红的朋友圈人数为,则可凑成的情侣数则为。
我的代码
易错点:容易不小心将par[i]理解为i所在树的根节点,实际上这只是父节点,要查询根节点需要用find函数。
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int par[20002];
//并查集初始化
void init(int x) {
for (int i = 1; i <= x; i++)
{
par[i] = i;
}
}
//查询
int find(int x) {
if (par[x] == x) {
return par[x];
}
else {
par[x] = find(par[x]);
return par[x];
}
}
//合并
void unite(int x, int y) {
x = find(x);
y = find(y);
par[x] = y;
}
//主函数
int main(void) {
int n;
int m; //A,B公司员工数
int p;
int q; //A,B公司朋友关系数
int x;
int y; //用于储存一对朋友
cin >> n >> m >> p >> q;
//初始化
init(n + m);
//合并集合
//输入男性:
for (int i = 1; i <= p; i++)
{
cin >> x >> y;
unite(x, y);
}
//输入女性:
for (int i = 1; i <= q; i++)
{
cin >> x >> y;
x = n - x;
y = n - y; //将女性编号负数换成正数
unite(x, y);
}
//查询集合
int A = find(1);
int B = find(n + 1);
int male = 0;
int female = 0;
for (int i = 1; i <= n+m; i++)
{
if (find(i) == A) {
male++;
}
else if (find(i) == B) {
female++;
}
}
cout << min(male, female);
return 0;
}