Connectivity(并查集)

本文介绍了如何使用并查集解决一道关于道路和铁路连通性的算法题。通过建立两种并查集分别记录公路和铁路的连通状态,然后找到它们的交集,计算每个点与其他点通过公路和铁路的共同连通点数量。在实现过程中需要注意完全路径压缩,以确保正确性。最后,给出了C++代码示例来演示解决方案。
摘要由CSDN通过智能技术生成

D - Connectivity

-abc049
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题意: 有n个点,k条公路, l l l条铁路,公路和铁路都是连接两个点的边,没有重边,只要A和B点能通过公路相通,就说明A和B使公路连接,铁路连接和这个一样,现在问,对于每个点来说,有多少个点是通过铁路和公路与这个点相连通(自己算连接自己)
(题意读了半天没读懂,样例都没研究出来 )
思路: 其实题目简化问题就是通过公路与当前点相连的点与通过铁路与当前点相连的点的交集。开两种并查集,来记录哪些点是通过公路和铁路与当前点相连,然后开个Map来存交集个数,Map里面存的就是父亲节点对的个数,对于集合里的元素来说,对于每个点通过找集合的祖先结点来计数,明显是可以的。
注意:并查集记录完后,要先完全路径压缩一遍,否则会出现父亲节点不是祖先结点的问题。

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef pair<int, int> PII;
int fa1[N], fa2[N];
int n, k, l;
int find(int x, int *fa) {
    if (x != fa[x]) fa[x] = find(fa[x], fa);
    return fa[x];
}
void Union(int x, int y, int *fa) {
    int fx = find(fa[x], fa), fy = find(fa[y], fa);
    if (fx != fy) {
        fa[fx] = fy;
    }
}
int main() {
    scanf("%d%d%d", &n, &k, &l);
    for (int i = 0; i < N; i++) {
        fa1[i] = i, fa2[i] = i;
    }
    while (k--) {
        int a, b;
        scanf("%d%d", &a, &b);
        Union(a, b, fa1);
    }
    while (l--) {
        int a, b;
        scanf("%d%d", &a, &b);
        Union(a, b, fa2);
    }
    for (int i = 1; i <= n; i++) {
        find(i, fa1), find(i, fa2);
    }
    map<PII, int> m;
    for (int i = 1; i <= n; i++) {
        m[{fa1[i], fa2[i]}]++;
    }
    for (int i = 1; i <= n; i++) {
        printf("%d ", m[{fa1[i], fa2[i]}]);
    }
    puts("");
    return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值