• 7-31 朋友圈 (25 分)(并查集)


    7-31 朋友圈 (25 分)

    某学校有N个学生,形成M个俱乐部。每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈。一个学生可以同时属于若干个不同的俱乐部。根据“我的朋友的朋友也是我的朋友”这个推论可以得出,如果A和B是朋友,且B和C是朋友,则A和C也是朋友。请编写程序计算最大朋友圈中有多少人。

    输入格式:

    输入的第一行包含两个正整数N(≤30000)和M(≤1000),分别代表学校的学生总数和俱乐部的个数。后面的M行每行按以下格式给出1个俱乐部的信息,其中学生从1~N编号:

    第i个俱乐部的人数Mi(空格)学生1(空格)学生2 … 学生Mi

    输出格式:

    输出给出一个整数,表示在最大朋友圈中有多少人。

    输入样例:

    7 4
    3 1 2 3
    2 1 4
    3 5 6 7
    1 6
    

    输出样例:

    4

    思路:类似与并查集的合并,对每个俱乐部看成一个集合,然后对这些集合进行合并

    第一种暴力:

    但是TLE:

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    
    using  namespace std;
    int pre[30005];
    int find(int x)
    
    {
    	if(x==pre[x])
    	{
    		return x;
    	}
    	else
    	{
    		return pre[x]=find(pre[x]);
    	}
    }
    void merge(int x,int y)
    {
    	int xx=find(x);
    	int yy=find(y);
    	if(xx!=yy)
    	{
    		pre[xx]=yy;
    	 } 
    }
    
    int main()
    {
        int n,m;
        cin>>n>>m;
        for(int t=1;t<=n;t++)
        {
        	pre[t]=t;
    	}
    	int b[1005];
        for(int t=0;t<m;t++)
        {
        	int k;
        	scanf("%d",&k);
        	for(int j=0;j<k;j++)
        	{
        		scanf("%d",&b[j]);
    		}
    		for(int j=0;j<k-1;j++)
    		{
    			merge(b[j],b[j+1]);
    		}
    	}
    	long long int maxn=0;
    	for(int t=1;t<=n;t++)
    	{
    		long long int sum=0;
    		if(find(t)==t)
    		{
    			for(int j=1;j<=n;j++)
    			{
    				if(find(j)==t)
    				{
    					sum++;
    				}
    			}
    		}
    		if(maxn<sum)
    		{
    			maxn=sum;
    		}
    	}
    	cout<<maxn<<endl;
    	return 0;
    }

    第二种利用类似于前缀和的思想进行求最大值,即可少一个循环的量,从而提高效率;

    AC代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    
    using  namespace std;
    int pre[30005];
    long long int summ[30005];
    int find(int x)
    
    {
    	if(x==pre[x])
    	{
    		return x;
    	}
    	else
    	{
    		return pre[x]=find(pre[x]);
    	}
    }
    void merge(int x,int y)
    {
    	int xx=find(x);
    	int yy=find(y);
    	if(xx!=yy)
    	{
    		pre[xx]=yy;
    		summ[yy]+=summ[xx];
    	 } 
    }
    
    int main()
    {
        int n,m;
        cin>>n>>m;
        
        for(int t=1;t<=n;t++)
        {
        	pre[t]=t;
        	summ[t]=1;
    	}
    	int b[1005];
        for(int t=0;t<m;t++)
        {
        	int k;
        	scanf("%d",&k);
        	for(int j=0;j<k;j++)
        	{
        		scanf("%d",&b[j]);
    		}
    		for(int j=0;j<k-1;j++)
    		{
    			merge(b[j],b[j+1]);
    		}
    	}
    	long long int maxn=0;
    	for(int t=1;t<=n;t++)
    	{ 
    	  maxn=max(maxn,summ[t]);
    	}
    	cout<<maxn<<endl;
    	return 0;
    }
  • 相关阅读:
    nginx syslog 配置
    通过granfana 以及prometheus 比较zulu 、oracle、openjdk 等jvm 运行
    cube.js 新版本试用preosto
    关于redash 自定义可视化以及query runner 开发的几篇文章
    通过redash query results 数据源实现跨数据库的查询
    cube.js 最近版本的一些更新
    zeebe 0.20.0 集群部署试用
    redash oracle 数据源docker 镜像
    使用jmx-exporter&&jmxtrans && nexus jmx 暴露nexus 系统指标信息
    jmxtrans docker-compose 运行
  • 原文地址:https://www.cnblogs.com/Staceyacm/p/10781951.html
Copyright © 2020-2023  润新知