zoukankan      html  css  js  c++  java
  • The Suspects(并查集入门)

    题目:http://www.fjutacm.com/Problem.jsp?pid=2021

    题意大概就是输入n,m,分别代表总共n个人,m组,每组输入k,后面再输入k个人表示是一组的,0号是嫌疑者,输出和0在一组的人数(嫌疑者的人数)。

    想看题目的点击这里哦:--->题目

    友情链接:--->点我

    咳咳,下面就是代码分析阶段,请看:

    #include<stdio.h>
    int fa[30005],n,rak[30005];
    void chushihua()//初始化,把每个人的父节点先设为自己。rak就是代表的人数(同一个集合的人数) 
    {
        for(int i=0;i<n;i++)//假设开始有n个集合 
        {
            fa[i]=i;
            rak[i]=1;
        }
    }
    int find(int x)
    {
        int r=x,temp;
        while(r!=fa[r])
            r=fa[r];
            while(x!=fa[x])//这里是路径压缩,让这棵树扁平化,把每个节点的父节点都直接变成根节点(让树变粗)。 
            {
                temp=fa[x];
                fa[x]=r;
                x=temp;
            }
            return x;
    }
    void hebing(int a,int b)//合并操作,也有点小细节 
    {
        a=find(a);
        b=find(b);
        if(a!=b)
        {
            fa[b]=a;
            rak[a]+=rak[b];//这里就把人数统计出来了,注意这里的a,b的位置。 
        }
    }
    int main(void)
    {
        int m,k,a,b;//这里的a表示的是每一组第一个学生 ,b表示的就是后面的学生 
        while(scanf("%d%d",&n,&m)&&n)//&&n表示当n和m同时为0就退出,但是不用写&&m,至于为什么,请读者自行领会 
        {
            chushihua();
            for(int i=0;i<m;i++)
            {
                scanf("%d",&k);
                scanf("%d",&a);
                for(int i=1;i<k;i++)
                {
                    scanf("%d",&b);
                    hebing(a,b);//将这些学生合并到一个集合里面。 
                }
            }
            printf("%d\n",rak[find(0)]);//输出和0学生一个集合总共的人数rak 
        }
        return 0;
    }

    小结一下:这个题是我学习并查集做的第二个题,比较基础适合并查集入门,感觉特别能体现出并查集的能力,如果没看懂题的话可能还是有点难度,不过也是巧,这道题讲的是有关病毒传染的,而作者所处的时间正好也是病毒四处传播,危害人民的时间,话不多说,武汉加油!

  • 相关阅读:
    分布式缓存Redis的集群-主从复制
    搭建私有Nuget服务
    分布式缓存Redis的持久化方式RDB和AOF
    .Net Core使用分布式缓存Redis:Lua脚本
    .Net Core使用分布式缓存Redis:数据结构
    .Net Core使用分布式缓存Redis:基础
    Android基础开发归档
    gdb 调试
    linux shell 常用表达式汇总
    V8 data struct
  • 原文地址:https://www.cnblogs.com/Mangata/p/12248857.html
Copyright © 2011-2022 走看看