TOJ并查集训练

Posted kannyi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TOJ并查集训练相关的知识,希望对你有一定的参考价值。

描述

2010年是xx国一个多灾多难的一年,灾难使该国的通讯系统遭到了重创,全国共有n个通讯站点,分别从0到n-1进行编号,通讯部门对每两个站点的线路进行了检测,现在要你确定有哪些站点是彼此连通的。

输入

输入数据有多组,每组数据的第一行包含两个整数n和m,其中n为通讯站点个数,接下来有m行,每一行有2个整数a和b,表示站点a和b通讯正常。其中1<=n<=250。
输入以EOF结束。

输出

针对每组输入,将所有连通的站点进行分组,并将每组按照站点从小到大的顺序输出,如果有多组,所有的组根据每组最小的站点编号进行从小到大的排序后输出。
每组数据输出之后加一个空行

样例输入

3 3
0 1
1 2
0 2
5 1
0 2

样例输出

0 1 2

0 2
1
3
4

#include<iostream>
using namespace std;
int top[255];
int find(int r)
{
    if(top[r]!=r)
    top[r]=find(top[r]);
    return top[r];
}
int join(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
    {
        top[fx]=fy;
    }
}
int init(int n)
{
    for(int i=0;i<n;i++)
    top[i]=i;
}
int main()
{
    int i,j,n,m,a,b;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init(n);
        for(j=0;j<m;j++)
        {
            scanf("%d%d",&a,&b);
            join(a,b);
        }
        int vis[255]={0};
        for(i=0;i<n;i++)
        {
            if(!vis[i])
            {
                printf("%d",i);
                vis[i]=1;
                for(j=0;j<n;j++)
                {
                    if(find(i)==find(j)&&vis[j]==0)   //如果上级相同且未访问过 
                    {
                        printf(" %d",j);
                        vis[j]=1;
                    }
                }
                cout<<endl;
            }
        }
        cout<<endl;
    }
    return 0;
} 

 

以上是关于TOJ并查集训练的主要内容,如果未能解决你的问题,请参考以下文章

第四周训练 | 并查集

2021牛客暑期多校训练营10 F.Train Wreck(栈,并查集,优先队列,贪心)

并查集 + 线段树 LA 4730 Kingdom

树的应用——并查集及实现代码

关于并查集的一切全在这里了

想要学会并查集吗?看我四十行代码实现它