这里我自己说一下我自己学的感受吧 。
int findset(int a) //不带路劲压缩
{
while(pa[a] != a)
{
a = pa[a];
}
return a;
}
void union_nodes(int a, int b) //集合合并
{
int a1 = findset(a);
int b1 = findset(b);
if(a1 != b1) //这个判定条件可选,主要是为了防止findset路径压缩的时候出现死循环
{
pa[a1] = b1; //如果存的是有向图,并且做题时集合中元素的顺序很重要,不能忽略,那么这里应该用"pa[a] = b;"
}
}
当时我刚刚接触的时候,也是看不太懂,然后自己去模拟一下过程,我粗劣的看成以下的结论
假设这里 有 甲乙丙丁茂, 这5个人,现在 你我要输入几组关系 ,然后询问某两个人是否有关系在
甲->茂 , 丙->茂 , 乙->丁
建一个数值 来表示 这五个人 【甲】【乙】【丙】【丁】【茂】
下标是 1 2 3 4 5
甲->茂 你可以看成是茂是甲的儿子或者是父亲(这里虽然是findfather但是我觉得 findson也是蛮好理解的)
这样 你就将 1 对应的【甲】改成茂
【茂】【乙】【丙】【丁】【茂】
下标是 1 2 3 4 5
同样的 丙->茂 改成 【茂】【乙】【茂】【丁】【茂】
下标是 1 2 3 4 5
乙->丁 改成 【茂】【丁】【茂】【丁】【茂】
下标是 1 2 3 4 5
改完之后 比如你要查询 甲丙有没有这样关系在 当你输入原本 在 1 ,3 两个值时你发现 甲不在了 你可以理解成 甲不知道 你去问一下和他有关系的茂看看 丙也一样 说我也不知道 你去问一下茂吧 就这样他们同时到了5 茂 发现5的值就是茂 你就可以理解成茂 并没有儿子 他是单独一人 而甲 , 丙都找到了茂,这样就说明他们有同样的 一个后代 “茂” 所以他们是有关系的
当询问 甲 乙 有没有关系 同样的过程 。 看到原本在1的甲 变成了茂 那我们就去 5 看看茂 发现茂没有变化过
询问乙的时候 ,发现乙变成了丁 这样询问4 丁,发现丁就丁。 那么丁和茂后面也没有后代去询问了,明显丁茂不存在关系,所以他们没有关系。
原文:http://www.cnblogs.com/0307jtx/p/3879865.html