并查集
1.其实并查集无非就是两个思想 : 并和查
2.那么我们为什么要进行并和查呢,这样做有什么作用呢
下面给出一道基础模板题
题意:
多个黑帮混战,但是由于都光着膀子,并且每个人只认识自己的师父(每个黑帮祖师爷只认识自己,毕竟目中无人嘛!)。现在有两个人碰在一起,但是他们不知道对方是敌人还是一个帮派的,请你来告诉他们(祖师爷一样就代表是同一个黑帮)
样例输入:
n,m n代表一共n个人,m代表一共m个师徒关系
接下来m行,每行两个整数,第一个整数代表徒弟的编号,第二个代表他的师父
接下来输入x,y请判断x和y是不是同一个黑帮的呢
样例输出:
yes or no
如题意:
1.每个团伙是不是都有一个祖师爷,如果我们取一个数组pre【n+5】来存下每个人的祖师爷,那我们最后是不是只用看看x和y的祖师爷相不相同就行了呢;
2.每次输入都将徒弟和师傅并成一个集合,并将徒弟的祖师爷变成师傅的祖师爷;
这里要特别强调一点,我们的pre【】数组在初始化的时候都要初始化成自己,因为在师徒关系未确定前,徒弟的祖师爷就是自己。同时在并集合的时候我们需要查一下
徒弟和师傅的祖师爷是否相同,如果相同就不用并了
下面给出核心并/查代码
查:
int find (int x)//定义成int类型是因为我们需要返回祖师爷的编后
{
int r=x;
while(r!=pre[r])//因为每个祖师爷的师傅都是自己
//所以当我们搜到人上面还有师傅且不是自己的时候,我们就继续搜索下去
r=pre[r];
return r;
}
//优化后续呈现
并
void join(int x,int y)
{
int kx=find(x);
int ky=find(y);
if(kx!=ky)//如果这两个人的祖师爷不同,那说明这两个人在不同集合,我们就需要合并
{
pre[x]=pre[y];
}
return//打上是个好习惯
}
//在并这个地方并没有什么优化
大佬勿喷
优化及其运用未完待续
thanks
Sabrina