【2024.9.26练习】P2078 朋友

题目描述


题目分析

涉及到元素分组问题,考虑使用并查集。由于同一个公司的员工都是同性,可以构造一个并查集,小明的朋友圈人数为A,小红的朋友圈人数为B,则可凑成的情侣数则为min(A,B)


我的代码

易错点:容易不小心将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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值