并查集的体会
新手向:
by U__0
直接上干货,废话不多说。
建立一个模型,有10个强盗,我们获取了一些关于他们之间关系的情报(X号强盗与Y号强盗是一伙的格式),分析至多有多少个团伙。
第一步,首先建立一个int dis【10】数组,记录每个强盗的老大,因为上来大家各自为政,所以初始化每个人的老大都是自己。
【注:最终更新这个数组,看有多少个人的老大依然是自己,就说明这个人成立了一个组织,代码就是if(dis[i]==i)n++;//n就是组织的数量】
第二步,分析情报,更新dis【10】数组。例如:3号和4号是一伙的。为了统一,我们默认输入的第一个强盗比较强一点,第二个输入弱一点,所以4号归顺3号,更新,dis[4]=3;
(注:如果你喜欢的话,第一个归顺第二个也可以,有人说这叫靠左原则)。
其实第二步省略了很多步骤,我们计算机判断时不知道3,4号都是自己一个人混的,其实我们应该让4号的老大归顺3号的老大。
然而刚才说的还是错的,实际代码的实现是使用递归的方法,寻找3号的最终老大(所谓最终老大,就是自己的老大还是自己的人)——x号强盗,以及4号的最终老大——y号强盗,找到这两个人,让后一个归顺前一个人(即dis[y]=x),这个时候y号强盗就不再是老大了,而是x号的小弟。
然后我们来看一下前面说过的寻找最终老大的递归方法
int xzld(int n) //n就是我们的目标强盗,而这个函数的目的就是找到该强盗的最终老大,返回值就是该老大的强盗编号
{
while(1)
{
if(dis[n]==n)return n; //假如n号的老大就是自己,那么说明他上面已经没有人了,没错,他就是我们要找的头目
else n=dis[n]; //假如n号的老大不是自己,那么我们需要转移目标(n=dis[n]),找到他的上线(接头上线?卧底的感觉,难道n号强盗还是个打入我军 //的特务?),他的直接领导有身份两种可能:
//一是我们要找的老大(直接输出),
//二是一个有点身份的小弟(这个人上面还有人,dis[n]!=n)我们需要循环继续转移目标(n=dis[n])判断他上线的身份,最终确认最一 //开始输入的n号强盗的最终老大是哪个强盗
}
}
新手向:
by U__0
直接上干货,废话不多说。
建立一个模型,有10个强盗,我们获取了一些关于他们之间关系的情报(X号强盗与Y号强盗是一伙的格式),分析至多有多少个团伙。
第一步,首先建立一个int dis【10】数组,记录每个强盗的老大,因为上来大家各自为政,所以初始化每个人的老大都是自己。
【注:最终更新这个数组,看有多少个人的老大依然是自己,就说明这个人成立了一个组织,代码就是if(dis[i]==i)n++;//n就是组织的数量】
第二步,分析情报,更新dis【10】数组。例如:3号和4号是一伙的。为了统一,我们默认输入的第一个强盗比较强一点,第二个输入弱一点,所以4号归顺3号,更新,dis[4]=3;
(注:如果你喜欢的话,第一个归顺第二个也可以,有人说这叫靠左原则)。
其实第二步省略了很多步骤,我们计算机判断时不知道3,4号都是自己一个人混的,其实我们应该让4号的老大归顺3号的老大。
然而刚才说的还是错的,实际代码的实现是使用递归的方法,寻找3号的最终老大(所谓最终老大,就是自己的老大还是自己的人)——x号强盗,以及4号的最终老大——y号强盗,找到这两个人,让后一个归顺前一个人(即dis[y]=x),这个时候y号强盗就不再是老大了,而是x号的小弟。
然后我们来看一下前面说过的寻找最终老大的递归方法
int xzld(int n) //n就是我们的目标强盗,而这个函数的目的就是找到该强盗的最终老大,返回值就是该老大的强盗编号
{
while(1)
{
if(dis[n]==n)return n; //假如n号的老大就是自己,那么说明他上面已经没有人了,没错,他就是我们要找的头目
else n=dis[n]; //假如n号的老大不是自己,那么我们需要转移目标(n=dis[n]),找到他的上线(接头上线?卧底的感觉,难道n号强盗还是个打入我军 //的特务?),他的直接领导有身份两种可能:
//一是我们要找的老大(直接输出),
//二是一个有点身份的小弟(这个人上面还有人,dis[n]!=n)我们需要循环继续转移目标(n=dis[n])判断他上线的身份,最终确认最一 //开始输入的n号强盗的最终老大是哪个强盗
}
}