zoukankan      html  css  js  c++  java
  • 7-25 朋友圈(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
     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 
     5 void Union( int x,int y);
     6 int Find( int x);
     7 
     8 int n,m;
     9 int bcj[30005];
    10 
    11 int main()
    12 {
    13     int i;
    14     int n1;
    15     int x,y;
    16     int ans = 0;
    17     scanf("%d %d",&n,&m);
    18     for( i=1; i<=n; i++)  bcj[i] = -1;   //初始化并查集
    19 
    20     while( m-- )
    21     {
    22         scanf("%d",&n1);
    23         for( i=1; i<=n1; i++)
    24         {
    25             if( i==1 )
    26             {
    27                 scanf("%d",&x);
    28             }
    29             else
    30             {
    31                 scanf("%d",&y);
    32                 Union(x,y);
    33             }
    34         }
    35     }
    36     for( i=1; i<=n; i++)
    37     {
    38         if( bcj[i]<ans )  ans = bcj[i];   //负数需寻找最小的值
    39     }
    40     ans = 0-ans;  //用负数表示集合中元素的个数
    41     printf("%d",ans);
    42     return 0;
    43 }
    44 
    45 //以下是并查集的两个基本操作
    46 int Find( int x)
    47 {
    48     if(bcj[x]<0) return x;
    49     return bcj[x] = Find(bcj[x]);
    50 }
    51 
    52 void Union( int x, int y)
    53 {
    54     x = Find(x);
    55     y = Find(y);
    56 
    57     if( x==y ) return;
    58     bcj[x] += bcj[y];
    59     bcj[y] = x;
    60 }
    这里再补充一道浙大的机试真题

    题目描述

        某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

    输入描述:

        测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。 
        注意:两个城市之间可以有多条道路相通,也就是说
        3 3
        1 2
        1 2
        2 1
        这种输入也是合法的
        当N为0时,输入结束,该用例不被处理。

    输出描述:

        对每个测试用例,在1行里输出最少还需要建设的道路数目。
    示例1

    输入

    4 2
    1 3
    4 3
    3 3
    1 2
    1 3
    2 3
    5 2
    1 2
    3 5
    999 0
    0
    

    输出

    1
    0
    2
    998

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 
     5 int Find( int x);
     6 void Union(int x, int y);
     7 
     8 int bcj[1002];
     9 
    10 int main()
    11 {
    12     int n,m;
    13     int x,y;
    14     int ans;
    15     int i;
    16     while( scanf("%d %d",&n,&m)!=EOF){
    17         if( n==0)  break;
    18 
    19         memset( bcj,-1,1002*sizeof(int));
    20         ans =0;
    21 
    22         while( m--){
    23             scanf("%d %d",&x,&y);
    24             Union( x,y);
    25         }
    26         for( i=1; i<=n; i++){
    27             if( bcj[i]<=-1) ans++;
    28         }
    29         printf("%d
    ",ans-1);
    30     }
    31     return 0;
    32 }
    33 
    34 int Find( int x)
    35 {
    36     if( bcj[x]<0 ) return x;
    37     return bcj[x] = Find( bcj[x]);
    38 }
    39 
    40 void Union(int x, int y)
    41 {
    42     x = Find( x );
    43     y = Find( y );
    44 
    45     if( x==y ) return;
    46     bcj[x] += bcj[y];
    47     bcj[y] = x;
    48 }



    在这个国度中,必须不停地奔跑,才能使你保持在原地。如果想要寻求突破,就要以两倍现在速度奔跑!
  • 相关阅读:
    TensorFlow实战5——TensorFlow实现AlexNet
    TensorFlow实战4——TensorFlow实现Cifar10识别
    TensorFlow实战3——TensorFlow实现CNN
    基础定理推证
    中考几何汇总
    Onenote
    高中数学教材整理
    云盘
    12-27问题
    圆锥曲线(1)
  • 原文地址:https://www.cnblogs.com/yuxiaoba/p/8408990.html
Copyright © 2011-2022 走看看