• POJ1611 The Suspects (并查集)


    本文出自:http://blog.csdn.net/svitter


    题意:0号学生染病,有n个学生,m个小组。和0号学生同组的学生染病,病能够传染。

                输入格式:n,m

                                    数量  学生编号1,2,3,4

                                    //m个分组

    题解:最为典型的并查集。

         解法一:求出全部的集合,然后求出0的parent,把parent为0的parent全部学生求出。

         解法二:在计算的过程中统计total;


    解法一:(一開始用的Vim写的在POJ上交出现 訪问禁止错误- - 不知道又奇妙的碰上了什么BUG,删了main函数中几个换行符就好了)

    #include <iostream>
    #include <stdio.h>
    using namespace std;
    
    int stu[30001];
    //the num of stu, group
    int n, m;
    
    void init()
    {
        for(int i = 0; i < n; i++)
            stu[i] = i;
    }
    
    int getParent(int a)
    {
        if(a == stu[a])
            return a;
        else
            return stu[a] = getParent(stu[a]);
    }
    
    void Merge(int a, int b)
    {
        if(getParent(a) == getParent(b))
            return;
    
        else
            stu[getParent(a)] = b;
    }
    
    
    int main()
    {
        int i, j;
        int deter, sum;
        int num;
        int temp1, temp2;
    
        while(scanf("%d%d", &n, &m))
        {
            if(n == 0 && m == 0)
                break;
            init();
            for(i = 0; i < m; i++)
            {
                scanf("%d", &num);
                scanf("%d", &temp1);
                for(j = 1; j < num; j++)
                {
                    scanf("%d", &temp2);
                    Merge(temp1, temp2);
                }
            }
            deter = stu[getParent(0)];
            sum = 1;
            for(i = 1; i < n; i++)
            {
                if(getParent(i) == deter)
                    sum++;
            }
    
            printf("%d
    ", sum);
        }
        return 0;
    }



    解法二:

    #include <iostream>
    #include <stdio.h>
    using namespace std;
    
    int stu[30001];
    int total[30001];
    //the num of stu, group
    int n, m;
    
    void init()
    {
        for(int i = 0; i < n; i++)
        {
            stu[i] = i;
            total[i] = 1;
        }
    }
    
    int getParent(int a)
    {
        if(a == stu[a])
            return a;
        else
            return stu[a] = getParent(stu[a]);
    }
    
    void merge(int a, int b)
    {
        if(getParent(a) == getParent(b))
            return;
    
        else
        {
            total[getParent(a)] += total[getParent(b)];
            stu[getParent(b)] = a;
        }
    }
    
    
    int main()
    {
        int i, j;
        int num;//record the group's num
        int temp1, temp2;
    
    
        while(scanf("%d%d", &n, &m))
        {
            if(n == 0 && m == 0)
                break;
            init();
            for(i = 0; i < m; i++)
            {
                scanf("%d", &num);
                scanf("%d", &temp1);
                for(j = 1; j < num; j++)
                {
                    scanf("%d", &temp2);
                    merge(temp1, temp2);
                }
            }
    
            printf("%d
    ", total[getParent(0)]);    //不能直接stu[0],由于stu[0]不一定是根节点。
        }
        return 0;
    }
    
    
    


  • 相关阅读:
    努力学习吧!
    C# 捕捉键盘事件
    oracle 11g 及 plsqldeveloper 相关操作
    Oracle 建表空间
    窗体程序 防止重复打开子窗体
    asp 下 ewebeditor 上传图片功能,在IE7,IE8 及更高版本上失效解决方法
    StringBuilder 在后台动态输出 html 代码
    起动停止 Oracle11g 三个服务的批处理写法
    MySQL 常用命令语句
    虚拟机—pychrm
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4233812.html
Copyright © 2020-2023  润新知