P2078 朋友

题目背景

小明在 A 公司工作,小红在 B 公司工作。

题目描述

这两个公司的员工有一个特点:一个公司的员工都是同性。

A 公司有 NN 名员工,其中有 PP 对朋友关系。B 公司有 MM 名员工,其中有 QQ 对朋友关系。朋友的朋友一定还是朋友。

每对朋友关系用两个整数 (X_i,Y_i)(Xi​,Yi​) 组成,表示朋友的编号分别为 X_i,Y_iXi​,Yi​。男人的编号是正数,女人的编号是负数。小明的编号是 11,小红的编号是 -1−1。

大家都知道,小明和小红是朋友,那么,请你写一个程序求出两公司之间,通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。

输入格式

输入的第一行,包含 44 个空格隔开的正整数 N,M,P,QN,M,P,Q。

之后 PP 行,每行两个正整数 X_i,Y_iXi​,Yi​。

之后 QQ 行,每行两个负整数 X_i,Y_iXi​,Yi​。

输出格式

输出一行一个正整数,表示通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。

输入输出样例

输入 #1复制

4 3 4 2
1 1
1 2
2 3
1 3
-1 -2
-3 -3

输出 #1复制

2

说明/提示

对于 30 \%30% 的数据,N,M \le 100N,M≤100,P,Q \le 200P,Q≤200;

对于 80 \%80% 的数据,N,M \le 4 \times 10^3N,M≤4×103,P,Q \le 10^4P,Q≤104;

对于 100 \%100% 的数据,N,M \le 10^4N,M≤104,P,Q \le 2 \times 10^4P,Q≤2×104。

1.这题也是并查集啦,用模板可以。

2.这题需要注意的一点是女生用的是负数,我们处理这个的时候改成她的相反数整数即可。

3.这一题就是先初始化各位朋友,然后去找当男性为1(这里指代的是小明)的祖宗,找到和 小明祖先(也就是说同属于朋友关系的人),统计即可。女生也是一样的,找到小红的祖宗,然后去暴力查找是可以AC的。

4.平常我们在并查集参数里面是没有指定数组的,因为通常我们使用的是全局变量,这里只需要加一个参数就可以重复使用并查集的代码。

代码如下:

#include<stdio.h>
#define N 10010
int male[N],female[N];
int getf(int x,int a[])
{
	if(x==a[x]) return x;
	return getf(a[x],a);
}
int merge(int x,int y,int a[])
{
	int p,q;
	p=getf(x,a);
	q=getf(y,a);
	if(p!=q)
	{
		a[q]=p;
	}
}
int sum(int x,int y,int a[])
{
	int p;
	p=getf(y,a);
	if(p==x) return 1;
	return 0;
}
int main()
{
	int  n,m,p,q,i,x,y,s1=1,s2=1;
	scanf("%d%d%d%d",&n,&m,&p,&q);
	for(i=1;i<=n;i++)
		male[i]=i;
	for(i=1;i<=m;i++)
		female[i]=i;
	for(i=0;i<p;i++)
	{
		scanf("%d%d",&x,&y);
		merge(x,y,male);
	}
	for(i=0;i<q;i++)
	{
		scanf("%d%d",&x,&y);
		merge(-x,-y,female);
	}
	x=getf(male[1],male);
	y=getf(female[1],female);
	for(i=2;i<=n;i++)
	{
		s1+=sum(x,male[i],male);
	}
	for(i=2;i<=m;i++)
	{
		s2+=sum(y,female[i],female);
	}
	printf("%d\n",s1>s2?s2:s1);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值