• C


    题意:现在是流感发病时期,学校有n个学生,学生编号为0~n-1,m个社团。0号学生是病毒携带者,如果有学生和病毒携带者在同一个社团,那么他也会变为病毒携带者。如  社团1(0,1 ,社团2( 1,2,3),那么 0,1,2,3都是病毒携带者。
    给出学生人数和社团情况,问,有多少个病毒携带者。
    思路:用并查集来合并集合就可以了,把每个社团当作一个集合和并。最后,找出0号学生所在的集合的根节点,然后遍历所有学生,如果和0号学生的根节点相同,说明他们在一个集合当中。
     
    ///仔细理解一下Find()操作!!
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include <string>
    using namespace std;
    int rk[30005],par[30005];
    int a[30005];
    int n,ans;
    void init()//初始化
    {
        for(int i=0;i<n;i++){
            rk[i]=0;
            par[i]=i;
        }
    }
    int Find(int x)//查找根节点
    {
        while(x!=par[x])
            x=par[x];
        return x;
    }
    void unite(int x, int y)//合并集合
    {
        x=Find(x);
        y=Find(y);
        if(x==y)
            return ;
        if(rk[x]<rk[y])
            par[x]=y;
        else{
            par[y]=x;
            if(rk[x]==rk[y])
                rk[x]++;
        }
    }
    int main()
    {
        int m,x;
        int a,b;
        while(~scanf("%d%d",&n,&m)&&(n+m)){
            init();
            for(int i=0;i<m;i++){
                scanf("%d",&x);
                scanf("%d",&a);//将每个社团的第一个人当作该社团的根节点合并
                for(int j=1;j<x;j++){
                    scanf("%d",&b);
                        unite(a,b);
                }
            }
            ans=1;
            for(int i=1;i<n;i++){//查找和0号学生在同一集合的学生
                if(Find(i)==Find(0))
                    ans++;
            }
            printf("%d
    ",ans);
        }
    }
    View Code

  • 相关阅读:
    宠物的生长(多态)
    程序员和程序狗
    表彰优秀学生(多态)
    [leetcode] Anagrams
    [leetcode] Add Two Numbers
    [leetcode] Add Binary
    [leetcode] 4Sum
    [leetcode] 3Sum Closest
    [leetcode] 3Sum
    函数成员修饰之私有方式
  • 原文地址:https://www.cnblogs.com/Levi-0514/p/9042486.html
Copyright © 2020-2023  润新知