当前位置: 代码迷 >> 综合 >> 带权并查集 poj 1182
  详细解决方案

带权并查集 poj 1182

热度:37   发布时间:2024-01-18 23:37:22.0

带权并查集和普通并查集最大的区别在于带权并查集合并的是可以推算关系的点的集合(可以通过集合中的一个已知值推算这个集合中其他元素的值)。而一般并查集合并的意图在于这个元素属于这个集合。带权并查集相当于把“属于”的定义拓展了一下,拓展为有关系的集合


1.poj1018 

如果用带权并查集,很复杂的一点就是路径的压缩,并且动物之间的指向性数学关系不明显很容易造成误判。

挑战程序设计竞赛给了一个很好的方法,把每个点化成3个点,每个i看待为3个点3*i,3*i+1,3*i+2,分别代表i属于A,i属于B,i属于C


并查集里面每一个组表示组内所有元素代表的情况都同时发生或者不发生

比如,题目给出5和15属于一个组

那么就把5*3和15*3,5*3+1和15*3+1,5*3+2和15*3+2合并(正常的并查集合并)

而比如5吃15,就把5-A和15-B合并,5-B和15-C合并,5-C和15-A合并


这样就可以用father来检测冲突了

比如要题目给出x,y同组,那么就要判断x-A与y-B,x-B与y-C,x-C与y-A是否同组(即是否存在互吃关系)
比如给出x吃y,就要判断x-A与y-A,x-B与y-B,x-c与y-C是否同组等信息(即是否以前同个物种)


2.奶牛的身高

 奶牛们在FJ的养育下茁壮成长。这天,FJ给了奶牛Bessie一个任务,去看看每个奶牛场中若干只奶牛的身高,由于Bessie是只奶牛,无法直接看出第i只奶牛的身高,而只能看出第i只奶牛与第j只奶牛的身高差,其中第i 只奶牛与第j只奶牛的身高差为A(i<=n)。当A大于0时表示这只奶牛比前一只奶牛高A cm,小于0时则是低。现在,FJ让Bessie总共去看了m次身高,当然也就传回给FJ m对奶牛的身高差,但是Bessie毕竟是奶牛,有时候眼睛可能会不好使……(大雾)你的任务是帮助FJ来判断是不是需要给Bessie看看眼睛了……
    注:Hj-Hi=A 注意T1的样例 注意注意注意 重要的事情说三遍。
输入描述 Input Description
    第一行为一个正整数w,表示有w组数据,即w个奶牛场,需要你判断。每组数据的第一行为两个正整数n和m,分别表示对应的奶牛场中的奶牛只数以及看了多少个对奶牛身高差。接下来的m行表示Bessie看m次后传回给FJ的m条信息,每条信息占一行,有三个整数s,t和v,表示第s只奶牛与第t只奶牛的身高差为v。
输出描述 Output Description
    包含w行,每行是”Bessie’s eyes are good”或”Bessie is blind.”(不含双引号),其中第i行为”Bessie’s eyes are good”当且仅当第i组数据,即无法从第i个奶牛场传回的身高差判断Bessie视力好不好;第i行为”Bessie is blind.”当且仅当第i组数据,即从第i个奶牛场传回的身高差是有问题的。
样例输入 Sample Input
2
3 3
1 3 10
2 3 5
1 2 5
4 3
1 4 100
3 4 50
1 3 100

对这一题就可以用带权并查集了,因为路径压缩变得无比简单,只要把路径相加就可以压缩了
输入a b  c之后,检查a与b的father
1.father相同
例如:.输入数据为 a b 3
如果fatherA与father B相同,那么假设fatehr的身高为m,A的身高为i,B的身高为j,那么权值的意义就是 m-i ,m-j
我们现在要查询的信息是是否i-j=3,我们已知m-i,m-j,那么只要用m-j-(m-i)就可以得到i-j了
2.father不同
例如:.输入数据仍然为 a b 3
那么我们现在需要连接A与B的father,怎么连接呢?
那么假设fatehrA,fatherB的身高为m,n。 A的身高为i,B的身高为j,那么权值的意义就是 m-i ,n-j
现在已知的是i-j=3,如果我们想连接fatherA与fatherB,那么我们需要知道n-i的值,也就是n-j-(m-i)即可

具体的算法实现就不写了。