题目背景
小明在 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;
}