# HG changeset patch
# User Balazs Dezso <deba@inf.elte.hu>
# Date 1229814782 -3600
# Node ID 561be42c4b9935bf3e30a922b8945b2397286a8f
# Parent  b0f74ca2e3ac2d7e7a63795d086d499323da8f0e
Bug fix in heap unionfind (ticket #197)

The minimum item in the unionfind tree might become inconsistent when
the split operation merges two subtrees which have equal keys. The
current changeset fix the problem. It also fix a wrong index.

diff -r b0f74ca2e3ac -r 561be42c4b99 lemon/unionfind.h
--- a/lemon/unionfind.h	Fri Dec 12 21:37:22 2008 +0100
+++ b/lemon/unionfind.h	Sun Dec 21 00:13:02 2008 +0100
@@ -1177,9 +1177,9 @@
             int pd = nodes[jd].parent;
             if (nodes[nodes[jd].next].size < cmax) {
               pushLeft(nodes[jd].next, nodes[jd].left);
-              if (less(nodes[jd].left, nodes[jd].next)) {
-                nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio;
-                nodes[nodes[jd].next].item = nodes[nodes[jd].left].item;
+              if (nodes[jd].item == nodes[pd].item) {
+                nodes[nodes[jd].next].prio = nodes[jd].prio;
+                nodes[nodes[jd].next].item = nodes[jd].item;
               }
               popLeft(pd);
               deleteNode(jd);
@@ -1188,9 +1188,10 @@
               int ld = nodes[nodes[jd].next].left;
               popLeft(nodes[jd].next);
               pushRight(jd, ld);
-              if (less(ld, nodes[jd].left)) {
+              if (less(ld, nodes[jd].left) || 
+                  nodes[ld].item == nodes[pd].item) {
                 nodes[jd].item = nodes[ld].item;
-                nodes[jd].prio = nodes[jd].prio;
+                nodes[jd].prio = nodes[ld].prio;
               }
               if (nodes[nodes[jd].next].item == nodes[ld].item) {
                 setPrio(nodes[jd].next);
@@ -1219,9 +1220,9 @@
             int pd = nodes[jd].parent;
             if (nodes[nodes[jd].prev].size < cmax) {
               pushRight(nodes[jd].prev, nodes[jd].right);
-              if (less(nodes[jd].right, nodes[jd].prev)) {
-                nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio;
-                nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item;
+              if (nodes[jd].item == nodes[pd].item) {
+                nodes[nodes[jd].prev].prio = nodes[jd].prio;
+                nodes[nodes[jd].prev].item = nodes[jd].item;
               }
               popRight(pd);
               deleteNode(jd);
@@ -1230,9 +1231,10 @@
               int ld = nodes[nodes[jd].prev].right;
               popRight(nodes[jd].prev);
               pushLeft(jd, ld);
-              if (less(ld, nodes[jd].right)) {
+              if (less(ld, nodes[jd].right) ||
+                  nodes[ld].item == nodes[pd].item) {
                 nodes[jd].item = nodes[ld].item;
-                nodes[jd].prio = nodes[jd].prio;
+                nodes[jd].prio = nodes[ld].prio;
               }
               if (nodes[nodes[jd].prev].item == nodes[ld].item) {
                 setPrio(nodes[jd].prev);
@@ -1400,7 +1402,14 @@
               }
               push(new_id, right_id);
               pushRight(new_id, ~(classes[r].parent));
-              setPrio(new_id);
+
+              if (less(~classes[r].parent, right_id)) {
+                nodes[new_id].item = nodes[~classes[r].parent].item;
+                nodes[new_id].prio = nodes[~classes[r].parent].prio;
+              } else {
+                nodes[new_id].item = nodes[right_id].item;
+                nodes[new_id].prio = nodes[right_id].prio;
+              }
 
               id = nodes[id].parent;
               classes[r].parent = ~new_id;
@@ -1440,7 +1449,14 @@
               }
               push(new_id, left_id);
               pushLeft(new_id, ~(classes[l].parent));
-              setPrio(new_id);
+
+              if (less(~classes[l].parent, left_id)) {
+                nodes[new_id].item = nodes[~classes[l].parent].item;
+                nodes[new_id].prio = nodes[~classes[l].parent].prio;
+              } else {
+                nodes[new_id].item = nodes[left_id].item;
+                nodes[new_id].prio = nodes[left_id].prio;
+              }
 
               id = nodes[id].parent;
               classes[l].parent = ~new_id;