Beispiel #1
0
// Search for an augmenting path in the graph graf.
// On success, the path data structure will include a list
// that forms the augmenting path. In this case, the last
// edge in the list is returned as the function value.
// On failure, returns 0.
edge edmonds::findpath() {
	vertex u,v,vp,w,wp,x,y; edge e, f;

	int t1, t2, t3;
	t1 = Util::getTime();

	blossoms->clear();
	for (u = 1; u <= graf->n(); u++) {
		state[u] = even; pEdge[u] = 0; origin[u] = u;
	}

	for (e = match->first(); e != 0; e = match->next(e)) {
		u = graf->left(e); v = graf->right(e);
		state[u] = state[v] = unreached;
	}
	UiList q(graf->m()); // list of edges to be processed in main loop
	for (e = 1; e <= graf->m(); e++) {
		if (state[graf->left(e)] == even ||
		    state[graf->right(e)] == even)
			q.addLast(e);
	}

	t2 = Util::getTime();
	pathInitTime += (t2-t1);
	while (!q.empty()) {
		stepCount++;
		e = q.first(); q.removeFirst();
		v = graf->left(e); vp = origin[blossoms->find(v)];
		if (state[vp] != even) {
			v = graf->right(e); vp = origin[blossoms->find(v)];
		}
		w = graf->mate(v,e); wp = origin[blossoms->find(w)];
		if (vp == wp) continue; // skip internal edges in a blossom
		if (state[wp] == unreached) {
			// w is not contained in a blossom and is matched
			// so extend tree and add newly eligible edges to q
			x = graf->mate(w,mEdge[w]);
			state[w] = odd;  pEdge[w] = e;
			state[x] = even; pEdge[x] = mEdge[w];
			for (f = graf->firstAt(x); f != 0;
			     f = graf->nextAt(x,f)) {
				if ((f != mEdge[x]) && !q.member(f))
					q.addLast(f);
			}
			continue;
		}
		u = nca(vp,wp);
		if (state[wp] == even && u == 0) {
			// vp, wp are different trees - construct path & return
			x = vp;
			while (pEdge[x] != 0) {
				x = origin[blossoms->find(
						graf->mate(x,pEdge[x]))];
			}
			y = wp;
			while (pEdge[y] != 0) {
				y = origin[blossoms->find(
						graf->mate(y,pEdge[y]))];
			}
			e = augpath->join(augpath->reverse(path(v,x)),e);
			e = augpath->join(e,path(w,y));
			t3 = Util::getTime();
			pathFindTime += (t3-t2);
			return e;
		} else if (state[wp] == even) {
			// vp and wp are in same tree - collapse blossom
			blossomCount++;
			x = vp;
			int fu = blossoms->find(u);
			int fx = blossoms->find(x);
			while (fx != fu) {
				fu = blossoms->link(fx,fu);
				if (state[x] == odd) {
					bridge[x].e = e; bridge[x].v = v;
					for (f = graf->firstAt(x); f != 0;
					     f = graf->nextAt(x,f))
						if (!q.member(f)) q.addLast(f);
				}
				x = origin[blossoms->find(
						graf->mate(x,pEdge[x]))];
				fx = blossoms->find(x);
			}
			y = wp;
			int fy = blossoms->find(y);
			while (fy != fu) {
				fu = blossoms->link(fy,fu);
				if (state[y] == odd) {
					bridge[y].e = e; bridge[y].v = w;
					for (f = graf->firstAt(y); f != 0;
					     f = graf->nextAt(y,f))
						if (!q.member(f)) q.addLast(f);
				}
				y = origin[blossoms->find(
						graf->mate(y,pEdge[y]))];
				fy = blossoms->find(y);
			}
			origin[fu] = u;
		} 
	}
	t3 = Util::getTime();
	pathFindTime += (t3-t2);
	return 0;
}
Beispiel #2
0
int main() {
	input();
	nca();
	//printf("%d",target1_parent[1]);
}