Codeforces 566D Restructuring Company

题意:n个人编号为1~n,有q条信息,每条信息包含三个整数a,b,c,如果a=1,就合并b和c,如果a=2,就合并编号为b到c的所有人,如果a=3,就判断b和c是不是同一组的

解题思路:很明显用并查集.维护相同集合间的关系用并查集。这里要注意要初始化0~n,因为编号是1~n,所以n也要初始化。如果a=1直接合并即可,如果a=2,要合并从b到c的所有人,如果简单的进行合并的话会超时,因为可能会重复合并,这时就要加一个next数组,用来存储下一个要合并的人,所以要将next[i]初始化为i+1。合并的时候还要定义一个临时变量temp,temp=next[i],然后另next[i]=next[c],举个例子:合并4~6,先合并4、5,这时temp=next[5]=5+1=6,next[5]=next[6]=7,下面合并5、6,temp=next[6]=7,next[6]=7,将temp的值赋给i,合并结束后next[4]=next[5]=next[6]=7,之所以要用next数组,是因为如果下一次要合并1~10的话,就不会再重复合并4~6了,节省时间,因为当合并到4时,next[4]=7,就直接从7开始合并了,这个方法值得学习

代码:

 

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int n,q;
int par[200005],rank[200005],next[200005];
void init()
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        rank[i]=0;
        next[i]=i+1;
    }
}
int find(int x)
{
    if(x==par[x])return x;
    else return par[x]=find(par[x]);
}
void unit(int x,int y)
{
    x=find(x),y=find(y);
    if(x==y)return ;
    if(rank[x]

 

 

 

 

 

你可能感兴趣的:(OJ刷题)