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。

思路讲解

用并查集来做,把小明认识的人包括自己放在一个集合里,把小红认识的人放在一个集合里,找两个集合人数最小值就行了

代码展示

#include<stdio.h>
int n,m,q,p;
int a,b,c,d;
int sum[10000];
int find(int x)//找最终父节点
{
    if(sum[x]==x)return x;
    return sum[x]=find(sum[x]);
}
void fun(int x,int y)
{
    if(find(x)!=find(y))
        sum[find(y)]=find(x);
}
int main()
{
    scanf("%d %d %d %d",&n,&m,&p,&q);
    int i,j;
    for(i=1;i<=n;i++)
        sum[i]=i;
    for(i=1;i<=p;i++)
    {
        scanf("%d %d",&a,&b);
        if(a<0)
        {
            a=-a;
            b=-b;
        }
        fun(a,b);
    }
    for(i=1;i<=n;i++)
    {
        if(find(i)==find(1))
            c++;
    }
    for(i=1;i<=m;i++)
        sum[i]=i;
    for(i=1;i<=q;i++)
    {
         scanf("%d %d",&a,&b);
        if(a<0)
        {
            a=-a;
            b=-b;
        }
        fun(a,b);
    }
     for(i=1;i<=m;i++)
    {
        if(find(i)==find(1))
            d++;
    }
    if(c>d)
        printf("%d",d);
    else printf("%d",c);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值