zoukankan      html  css  js  c++  java
  • POJ-1611 并查集

    Time Limit: 1000MS   Memory Limit: 20000KB   64bit IO Format: %I64d & %I64u

    []   [Go Back]   [Status]  

    Description

    Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others. 
    In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP). 
    Once a member in a group is a suspect, all members in the group are suspects. 
    However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.

    Input

    The input file contains several cases. Each test case begins with two integers n and m in a line, where n is the number of students, and m is the number of groups. You may assume that 0 < n <= 30000 and 0 <= m <= 500. Every student is numbered by a unique integer between 0 and n−1, and initially student 0 is recognized as a suspect in all the cases. This line is followed by m member lists of the groups, one line per group. Each line begins with an integer k by itself representing the number of members in the group. Following the number of members, there are k integers representing the students in this group. All the integers in a line are separated by at least one space. 
    A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.

    Output

    For each case, output the number of suspects in one line.

    Sample Input

    100 4
    2 1 2
    5 10 13 11 12 14
    2 0 1
    2 99 2
    200 2
    1 5
    5 1 2 3 4 5
    1 0
    0 0

    Sample Output

    4
    1
    1

    并查集这个东西,确实非常好用。
    并查集学起来很简单,通过想象一下图,也是很好理解的。。通过用father[x]将所有在一个集合的元素并进来成一个大集合。
    比较巧妙的地方,在于路径压缩,使得原本时空占用都比较大的一个递归,变得只有O(1)。
    用代码讲比较好

    #include <iostream>
    #include <cstdio>
    #define maxn 30005
    using namespace std;
    int father[maxn];
    int size[maxn];
    int findset(int x)
    {
        if (x!=father[x])
            father[x]=findset(father[x]); //这里巧妙的用了路径压缩,让每个点直接保留的是最上面的root节点,之后再查找起来,一步就到了顶点。
        return father[x];
    }
    void unionset(int x,int y)//这里进行不同集合的合并
    {
        int r1=findset(x);
        int r2=findset(y);
        if (r1==r2) return;
        if (size[r1]<=size[r2]) //我试了不进行判断,默认以r1为顶点,将其他有关联的集合全部指向它。。但是样例能过,OJ过不了。。一定要加判断才过得了
        {
            father[r1]=r2;    //其实我怎么想一下,我觉得不判断也没问题啊。。强制集合内的第一个点为顶点,,还没想明白为什么会有问题。
            size[r2]+=size[r1]; //size每次加多少,根据题目要求,这道题要求集合内总人数,无疑是直接加集合内人数。
        }
        else
        {
            father[r2]=r1;
            size[r1]+=size[r2];
        }
    }
    int main()
    {
        int n,m;
        while (scanf("%d %d",&n,&m))
        {
            if (n==0) break;
            for (int i=0;i<n;i++)
            {
                father[i]=i;
                size[i]=1;
            }
            for (int j=0;j<m;j++)
            {
                int k,a;
                scanf("%d %d",&k,&a);
                for (int q=0;q<k-1;q++)
                {
                    int b;
                    scanf("%d",&b);
                    unionset(a,b);
                }
            }
            int ans=size[findset(0)];
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    数据可视化 —— 数据流图(Data Flow Diagram)
    TensorFlow 实战(四)—— tensor 的认识
    数据集(benchmark)、常用数据集的解析(cifar-10、)
    HDU--杭电--4504--威威猫系列故事——篮球梦--DP
    android打包apk时混淆遇到的问题
    C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
    按 Eclipse 开发喜好重新布置 cocos2dx 目录层次
    HDU--杭电--4502--吉哥系列故事——临时工计划--背包--01背包
    (step6.3.2)hdu 1068(Girls and Boys——二分图的最大独立集)
    flashcache中应用device mapper机制
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3227044.html
Copyright © 2011-2022 走看看