并查集-按秩合并

1239: 中山学院 ACM小组

Time Limit: 1 Sec  Memory Limit: 64 MB

Submit: 79  Solved: 21

[Submit][Status][Web
Board
]

Description

经过几年的发展,中山学院 ACM队伍越来越庞大,水平越来越高,影响力也越来越大。随着人员数量的壮大,为了营造一个良好的队内之间沟通讨论氛围,教练组决定让队员之间以小组的形式进行讨论。而教练组又希望所有认识的人都在同一组里面讨论,以提高大家的积极性。而这里的认识可以是直接认识或是间接认识(如果A和 B认识,B 和 C认识,这时A和C可以通过B从而使三个人成为同一个小组的成员。四个人以上的做类似的处理。),假如有一个人他谁都不认识,那么没办法了,他只能自己呆在角落发呆了。当然,他自己也算一个讨论组。同时每个队员都有一个唯一的编号,编号从0
到 n-1(n是队员总数)。现在队伍里面有n个人,跟m组关系,每组关系有两个数a,b,表示a跟b相互认识。那么现在问你,我们学校ACM队伍里面一共组成了多少个讨论组?并且对于每个队员,你是否知道他所属讨论组的人数有多少?

Input

对于每组输入,第一行为两个数n 和 m, (1 <=n <=100,1 <=m<=100),分别代表ACM队内的总人数n和m组关系。接下来的m行,每行有两个数 a 和b,a 和b 是队员的编号,表示 a 和 b认识(0 <= a,b<=n-1)。下面一行输入一个整数k,代表有k组询问,后面的k行每行输入一整数 x,表示此次询问编号为x 的队员所属小组的人数。 (n 和m同时为0时输入结束)

Output

第一行输出讨论小组的数目(格式为”X groups in Zsc_Acmer Camp”,其中X表示讨论小组数目)后面的k行,每一行输出对应询问的回答。

Sample Input

5 30 11 20 2501234

Sample Output

3 groups in Zsc_Acmer Camp33311

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int d[500],s[500];
int find(int x)
{
    int k,j,r;
    r=x;
    while(r!=d[r])
        r=d[r];
    k=x;
    while(k!=r)
    {
        j=d[k];
        d[k]=r;
        k=j;
    }
    return r;
}
void unio(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y)
        return ;
    if(s[x]>=s[y])
    {
        d[y]=x;
        s[x]+=s[y];
    }
    else
    {
        d[x]=y;
        s[y]+=s[x];
    }
}
int main()
{
    int n,m,a,b,ki,tt;
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)
            break;
        for(int i=0;i<n;i++)
        {
            d[i]=i;
            s[i]=1;
        }
        while(m--)
        {
            scanf("%d%d",&a,&b);
            unio(a,b);
        }
        int cas=0;
        for(int i=0;i<n;i++)
        {
            if(d[i]==i)
                cas++;
        }
        printf("%d groups in Zsc_Acmer Camp\n",cas);
        scanf("%d",&ki);
        while(ki--)
        {
            scanf("%d",&tt);
            int aa=find(tt);
            printf("%d\n",s[aa]);
        }
    }
    return 0;
}

时间: 2024-08-08 11:14:49

并查集-按秩合并的相关文章

BZOJ4025 二分图 分治 并查集 二分图 并查集按秩合并 带权并查集

原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中第$i$条边连接节点$x_i,y_i$,并且在$start_i$时刻出现,在$end_i$时刻消失.问每一个时刻的图是不是二分图. $n\leq 10^5,m\leq 2\times 10^5,T\leq 10^5$ 题解 真是一道好题. 做这题我才发现我从来没写过按秩合并的并查集QAQ. 先考虑按

HDU 1811 Rank of Tetris(并查集按秩合并+拓扑排序)

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9267    Accepted Submission(s): 2668 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

HDU1865--More is better(统计并查集的秩(元素个数))

More is better Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 327680/102400 K (Java/Others)Total Submission(s): 25168    Accepted Submission(s): 9045 Problem Description Mr Wang wants some boys to help him with a project. Because the project

Knight Tournament 伪并查集(区间合并)

Knight Tournament Hooray! Berl II, the king of Berland is making a knight tournament. The king has already sent the message to all knights in the kingdom and they in turn agreed to participate in this grand event. As for you, you're just a simple pea

bzoj2733 [ HNOI2012 ] -- 并查集+线段树合并

用并查集记录每个联通块的根节点,每个联通块建一棵线段树,合并时合并线段树就可以了. 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define N 100010 6 struct node{ 7 int l,r,x; 8 }c[N*20]; 9 int i,j,k,n,m,l,r,a[N],x,y,Rt[N],Num,b[N],f[N],

[BZOJ2733] [HNOI2012]永无乡(并查集 + 线段树合并)

传送门 一看到第k大就肯定要想到什么权值线段树,主席树,平衡树之类的 然后就简单了 用并查集判断连通,每个节点建立一颗权值线段树,连通的时候直接合并即可 查询时再二分递归地查找 时间复杂度好像不是很稳定...但hzwer都用这种方法水过.. 正解好像是平衡树+启发式合并,以后学TT #include <cstdio> #include <iostream> #define N 100001 int n, m, q, cnt; int a[N], f[N], sum[N * 20],

并查集(集合合并) + 缩点

正解是dfs的一道题目被我以为成了并查集,结果坑了队友.现在分析一下自己当时为什么会想成是并查集呢. 题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 题意:告诉一张n点m边的图,求哪些边是桥.其实就是缩点,然而却大脑短路,直接认定是并查集了,现在的我真的不能理解当时的自己.... 当时想的是把所有的环缩成一个点,然后剩下的边就是桥了,缩点,第一时间想的就是并查集,其实并查集的操作一般有三个: 1.初始化 把

Restructuring Company和Almost Union-Find 并查集的区间合并与并查集的删除

Restructuring Company Even the most successful company can go through a crisis period when you have to make a hard decision - to restructure, discard and merge departments, fire employees and do other unpleasant stuff. Let's consider the following mo

51nod 1515 明辨是非 并查集 + set + 启发式合并

给n组操作,每组操作形式为x y p. 当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等:否则输出NO,并忽略此次操作. 当p为0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 :否则输出NO,并忽略此次操作. Input 输入一个数n表示操作的次数(n<=1*10^5) 接下来n行每行三个数x,y,p(x,y<=1*10^8,p=0 or 1) Output 对于n行操作,分别输出n行YES或者NO Input示例 3 1 2 1 1 3 1