zoukankan      html  css  js  c++  java
  • POJ-图论-并查集模板

    POJ-图论-并查集模板

    1、init:把每一个元素初始化为一个集合,初始化后每一个元素的父亲节点是它本身,每一个元素的祖先节点也是它本身(也可以根据情况而变)。

    void init()
    {
        for (int i = 0; i < n; i++) p[i] = i;//p[i]即为i结点的父亲节点的编号
    }

    2、find(x) :查找一个元素所在的集合,即找到这个元素所在集合的祖先,判断两个元素是否属于同一集合,只要看他们所在集合的祖先是否相同即可。合并两个集合,也是使一个集合的祖先成为另一个集合的祖先。

    int find(int x)
    {
        return x == p[x] ? x : p[x] = find(p[x]);//已包含路径压缩
    }

    3、Union(x,y) :合并x,y所在的两个集合,利用find()找到其中两个集合的祖先,将一个集合的祖先指向另一个集合的祖先。如图

    void Union(int x, int y)
    {
        x = find(x);
        y = find(y);
    
        if (x == y) return;
        else p[y] = x;//把y树合并到x树上,以x为根
    }

    POJ 2524 Ubiquitous Religions

    解题思路

    并查集入门题,求出有多少个不同的连通分量即可。

    AC代码

    #include<cstdio>
    const int N = 50500;
    
    int p[N];//父结点数组
    int n, m;//结点数量和结点关系数量
    
    void init()
    {
        for (int i = 0; i < n; i++)p[i] = i;//初始化,父结点为自身,单结点为孤立树
    }
    
    int find(int x)//找到x所在树的根结点
    {
        return (x == p[x]) ? x : p[x] = find(p[x]);
    }
    
    
    void Union(int x, int y)//合并,将y树合并到x树上
    {
        x = find(x);
        y = find(y);
        if (x == y)return;
        else p[y] = x;
    }
    
    int main()
    {
        int cnt = 1;
        while (scanf("%d%d", &n, &m)!=EOF)
        {
            if (n == 0 && m == 0) break;
            int x, y;
            init();//初始化,清空数组
            for (int i = 0; i < m; i++)
            {
                scanf("%d%d", &x, &y);
                Union(x, y);
            }
            int ans = 0;
            for (int i = 0; i < n; i++)
            {
                if (i == p[i])ans++;
            }
            printf("Case %d: %d
    ", cnt++, ans);
        }
        return 0;
    }

    POJ 1611 The Suspects

    解题思路

    至于一个小组有多个人,从第二个人起与第一个人所在小组合并就好。

    AC代码

    #include<cstdio>
    const int N = 30300;
    
    int p[N];//父结点数组
    int n, m;//结点数量和结点关系数量
    
    void init()
    {
        for (int i = 0; i < n; i++)p[i] = i;//初始化,父结点为自身,单结点为孤立树
    }
    
    int find(int x)//找到x所在树的根结点
    {
        return (x == p[x]) ? x : p[x] = find(p[x]);
    }
    
    
    void Union(int x, int y)//合并,将y树合并到x树上
    {
        x = find(x);
        y = find(y);
        if (x == y)return;
        else p[y] = x;
    }
    
    int main()
    {
        while (scanf("%d%d", &n, &m)!=EOF)
        {
            if (n == 0 && m == 0) break;
            int groupNum, x, y;
            init();//初始化,清空数组
            while(m--)
            {
                scanf("%d%d", &groupNum, &x);
                while (--groupNum)
                {
                    scanf("%d", &y);
                    Union(x, y);//每个组员与第一个组员所在团体合并
                }
            }
            int ans = 0;
            for (int i = 0; i < n; i++)//自己也是患者
            {
                if (find(i) == find(0))ans++;//和0号有关系的学生
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    Windows Phone 8 Wallet 手机钱包 / 电子钱包
    Windows Phone 8 In app purchase 应用内购买 / 应用内支付
    Windows Phone 8 适应多屏分辨率
    Windows phone 8 基于定位的后台应用
    Windows Phone 8 Nokia地图控件
    Windows Phone 8 MDIL编译与代码混淆工具
    Windows Phone 8 近场通信 NFC / Bluetooth Proximity
    Windows Phone 8 镜头应用 Lenses for Windows Phone 8
    Windows Phone 8 与 windows 8 开发技术概览
    嵌入式成长轨迹54 【Zigbee项目】【CC2430基础实验】【系统睡眠工作状态】
  • 原文地址:https://www.cnblogs.com/yun-an/p/11101947.html
Copyright © 2011-2022 走看看