公司通婚
Description
大连惊现两个很奇葩的互联网公司!
这两个公司(A公司和B公司)的员工有一个特点:一个公司的员工都是同性。
A公司有N名员工,其中有P对朋友关系。B公司有M名员工,其中有Q对朋友关系。朋友的朋友一定还是朋友。
每对朋友关系用两个整数(Xi,Yi)组成,表示朋友的编号分别为Xi,Yi。男人的编号是正数,女人的编号是负数。小邵的编号是1,小刘的编号是-1.
大家都知道,小邵和小刘是朋友,那么,请你写一个程序求出两公司之间,通过小邵和小刘认识的人最多一共能配成多少对情侣。(包括他们自己)
input
第1行,4个空格隔开的正整数N,M,P,Q。
之后P行,每行两个正整数Xi,Yi。
之后Q行,每行两个负整数Xi,Yi。
output
输出一个正整数,表示通过小邵和小刘认识的人最多一共能配成多少对情侣。
Sample Input 1
4 3 4 2
1 1
1 2
2 3
1 3
-1 -2
-3 -3
Sample Output
2
题解
该题是一道并查集的题,但是需要稍微修改并查集最后祖先的合并方式。
小邵和小刘的编号为1和-1,所以我们可以对两个公司使用两个并查集。
首先对A公司使用并查集,并查集的最终合并我们取最小的那个为祖先,同理B公司也是,那么最终合并后的结果,我们只需要对每个公司的员工找到其祖先是否为1,如果为1则代表该员工认识一号编号的人。
我们最后计数每个公司的祖先为1的人数,因为题目是问可以凑成多少对,那么我们只需要取两个公司中祖先为1的个数最小的那一个即可。
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 10010;
int f1[N], f2[N];
int siz1[N], siz2[N];
int n, m, p, q;
int find(int f[],int x) {
if(f[x] != x) f[x] = find(f,f[x]);
return f[x];
}
void merge(int f[],int siz[],int a,int b) {
int t1 = find(f,a);
int t2 = find(f,b);
if(t1 != t2) {
f[t1] = t2;
siz[t2] += siz[t1];
}
}
int main()
{
cin >> n >> m >> p >> q;
for(int i = 1;i <= n;i ++) {
f1[i] = i;
siz1[i] = 1;
}
for(int i = 1;i <= m;i ++) {
f2[i] = i;
siz2[i] = 1;
}
while(p --) {
int a, b;
cin >> a >> b;
merge(f1,siz1,a,b);
}
while(q --) {
int a, b;
cin >> a >> b;
merge(f2,siz2,-a,-b);
}
cout << min(siz1[find(f1,1)],siz2[find(f2,1)]) << endl;
return 0;
}
```