并查集 + 路径压缩 + 例题

借鉴:传送门
思路:并查集即将所有的独立集合中,有关系的集合链接起来,形成一个新的集合,最后达到划分众多数据的目的。
运用了数据结构中的树来实现。
核心构成有pre[i] = root.代表i的父类是root. i的超级父类即为i与root的共同父类。可以理解为超类是i与root的掌门,root是i的上级。

find函数 查找超级父类 同时实现路径压缩。

join函数 将有关系的两个点的父类放在同一个集合中达到减小划分区域的目的。即为并。
传送门
AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace  std;
int pre[1005];
int n, m;
int Find(int root)
{
    int son = root;
    while(pre[root] != root)
        root = pre[root];
    while(son != root)//tmp保存前驱结点
    {
        int tmp = pre[son];
        pre[son] = root;
        son = tmp;
    }
    return root;
}
int main()
{
    while(~scanf("%d", &n) && n != 0)
    {
        scanf("%d", &m);
        for(int i = 1; i <= n; i++)
            pre[i] = i;
        int cnt = n;
        for(int i = 1; i <= m; i++)
        {
            int u, v;
            int root1, root2;
            scanf("%d %d", &u, &v);
            root1 = Find(u);
            root2 = Find(v);
            if(root1 != root2)
            {
                pre[root1] = root2;
                cnt--;
            }
        }
        printf("%d\n", cnt - 1);
        memset(pre, 0, sizeof pre);
    }
    return 0;
}

发布了244 篇原创文章 · 获赞 8 · 访问量 5115

猜你喜欢

转载自blog.csdn.net/weixin_43960370/article/details/104083043
今日推荐