template <typename captype, typename tcaptype, typename flowtype> void IBFSGraph<captype, tcaptype, flowtype>::adoptionSink()
{
	node *x, *y;
	arc *a, *aEnd;
	arc aTmp;
	int minLabel;

	while (orphanFirst != END_OF_ORPHANS)
	{
		x = orphanFirst;
		orphanFirst = x->nextOrphan;

		// we need PREVIOUSLY_ORPHAN vs NULL
		// in order to establish whether the node
		// has already started a "new parent" scan
		// while in this level or not (used in ADD_ORPHAN)
		x->nextOrphan = PREVIOUSLY_ORPHAN;
		a = x->parent;
		x->parent = NULL;
		aEnd = (x+1)->firstArc;

		// check for rehook
		if (x->label != -1)
		{
			minLabel = x->label + 1;
			for (; a != aEnd; a++)
			{
#ifdef STATS
				orphanArcs1++;
#endif
				y = a->head;
				if (a->rCap != 0 && 
					y->parent != NULL &&
					y->label == minLabel)
				{
					x->parent = a;
					x->nextSibling = NODE_PTR_TO_INDEX(y->firstSon);
					y->firstSon = x;
					break;
				}
			}
		}

		// give up on node - relabel it!
		if (x->parent == NULL)
		{
			minLabel = -(activeLevel+1);
			for (a=x->firstArc; a != aEnd; a++)
			{
#ifdef STATS
				orphanArcs2++;
#endif
				y = a->head;
				if (a->rCap != 0 &&
					y->parent != NULL &&
					y->label < 0 &&
					y->label > minLabel)
				{
					minLabel = y->label;
					x->parent = a;
					if (minLabel == x->label) break;
				}
			}

			// create orphan sons
			for (y=x->firstSon; y; y=NODE_INDEX_TO_PTR(y->nextSibling))
			{
#ifdef STATS
				orphanArcs3++;
#endif
				if (minLabel == x->label && 
					y->parent != y->firstArc)
				{
					aTmp = *(y->parent);
					*(y->parent) = *(y->firstArc);
					*(y->firstArc) = aTmp;
					y->parent->sister->sister = y->parent;
					y->firstArc->sister->sister = y->firstArc;
				}
				ADD_ORPHAN_BACK(y);
			}

			x->firstSon = NULL;
			if (x->parent == NULL)
			{
				x->nextOrphan = NULL;
			}
			else
			{
				x->label = (minLabel-1);
				x->nextSibling = NODE_PTR_TO_INDEX(x->parent->head->firstSon);
				x->parent->head->firstSon = x;
				if (minLabel == -activeLevel)
				{
					SET_ACTIVE(x);
				}
			}
		}
	}
}
示例#2
0
template <typename captype, typename tcaptype, typename flowtype> void IBFSGraph<captype, tcaptype, flowtype>::adoptionSink()
{
	node *i, *j;
	arc *a, *a_end;
	arc tmp_a;
	int min_label;

	while (orphanFirst != END_OF_ORPHANS)
	{
		// terminalCap is used as a next pointer for the orphans list
		i = orphanFirst;
		orphanFirst = i->nextOrphan;

#ifdef STATS
		statsNumOrphans++;
//		if (orphanPhaseNodesHash[i-nodes] == false)
//		{
//			orphanPhaseNodesHash[i-nodes] = true;
//			orphanPhaseLabels[numOrphanPhaseNodes] = -(i->label);
//			orphanPhaseNodes[numOrphanPhaseNodes] = i;
//			numOrphanPhaseNodes++;
//		}
#endif
		// we need PREVIOUSLY_ORPHAN vs NULL
		// in order to establish whether the node
		// has already started a "new parent" scan
		// while in this level or not (used in ADD_ORPHAN)
		i->nextOrphan = PREVIOUSLY_ORPHAN;
		a = i->parent;
		i->parent = NULL;
		a_end = (i+1)->firstArc;

#ifdef COUNT_RELABELS
		if (scans[i-nodes] == 0)
		{
			scanIndices.push_back(i-nodes);
		}
		if ((scans[i-nodes]%2) == 0)
		{
			scans[i-nodes]++;
		}
#endif

		// check for rehook
		if (i->label != -1)
		{
			min_label = i->label + 1;
			for (; a != a_end; a++)
			{
#ifdef STATS
				orphanArcs1++;
#endif
				j = a->head;
				if (a->rCap != 0 && 
					j->parent != NULL &&
					j->label == min_label)
				{
					i->parent = a;
					i->nextSibling = NODE_PTR_TO_INDEX(j->firstSon);
					j->firstSon = i;
					break;
				}
			}
		}

		// give up on node - relabel it!
		if (i->parent == NULL)
		{
#ifdef COUNT_RELABELS
			scans[i-nodes]++;
#endif

			min_label = -(activeLevel+1);
			for (a=i->firstArc; a != a_end; a++)
			{
#ifdef STATS
				orphanArcs2++;
#endif
				j = a->head;
				if (a->rCap != 0 &&
					j->parent != NULL &&
					j->label < 0 &&
					j->label > min_label)
				{
					min_label = j->label;
					i->parent = a;
					if (min_label == i->label) break;
				}
			}
			for (j=i->firstSon; j; j=NODE_INDEX_TO_PTR(j->nextSibling))
			{
#ifdef STATS
				orphanArcs3++;
#endif
				if (min_label == i->label && 
					j->parent != j->firstArc)
				{
					tmp_a = *(j->parent);
					*(j->parent) = *(j->firstArc);
					*(j->firstArc) = tmp_a;
					j->parent->sister->sister = j->parent;
					j->firstArc->sister->sister = j->firstArc;
				}
				ADD_ORPHAN_BACK(j);
			}
			i->firstSon = NULL;
			if (i->parent == NULL)
			{
				i->nextOrphan = NULL;
			}
			else
			{
				i->label = (min_label-1);
				i->nextSibling = NODE_PTR_TO_INDEX(i->parent->head->firstSon);
				i->parent->head->firstSon = i;
				if (min_label == -activeLevel)
				{
					SET_ACTIVE(i);
				}
			}
		}
	}
}