diff --git a/findloop.c b/findloop.c index ffda12d..4ebdea1 100644 --- a/findloop.c +++ b/findloop.c @@ -14,7 +14,7 @@ #include "puzzles.h" struct findloopstate { - int parent, child, sibling; + int parent, child, sibling, component_root; bool visited; int index, minindex, maxindex; int minreachable, maxreachable; @@ -57,6 +57,33 @@ bool findloop_is_loop_edge(struct findloopstate *pv, int u, int v) return !(pv[u].bridge == v || pv[v].bridge == u); } +static bool findloop_is_bridge_oneway( + struct findloopstate *pv, int u, int v, int *u_vertices, int *v_vertices) +{ + int r, total, below; + + if (pv[u].bridge != v) + return false; + + r = pv[u].component_root; + total = pv[r].maxindex - pv[r].minindex + 1; + below = pv[u].maxindex - pv[u].minindex + 1; + + if (u_vertices) + *u_vertices = below; + if (v_vertices) + *v_vertices = total - below; + + return true; +} + +bool findloop_is_bridge( + struct findloopstate *pv, int u, int v, int *u_vertices, int *v_vertices) +{ + return (findloop_is_bridge_oneway(pv, u, v, u_vertices, v_vertices) || + findloop_is_bridge_oneway(pv, v, u, v_vertices, u_vertices)); +} + bool findloop_run(struct findloopstate *pv, int nvertices, neighbour_fn_t neighbour, void *ctx) { @@ -94,6 +121,7 @@ bool findloop_run(struct findloopstate *pv, int nvertices, */ pv[v].sibling = pv[root].child; pv[root].child = v; + pv[v].component_root = v; debug(("%d is new child of root\n", v)); u = v; @@ -116,6 +144,7 @@ bool findloop_run(struct findloopstate *pv, int nvertices, pv[w].child = -1; pv[w].sibling = pv[u].child; pv[w].parent = u; + pv[w].component_root = pv[u].component_root; pv[u].child = w; } diff --git a/puzzles.h b/puzzles.h index 2895fd4..6012478 100644 --- a/puzzles.h +++ b/puzzles.h @@ -590,6 +590,18 @@ bool findloop_run(struct findloopstate *state, int nvertices, */ bool findloop_is_loop_edge(struct findloopstate *state, int u, int v); +/* + * Alternative query function, which returns true if the u-v edge is a + * _bridge_, i.e. a non-loop edge, i.e. an edge whose removal would + * disconnect a currently connected component of the graph. + * + * If the return value is true, then the numbers of vertices that + * would be in the new components containing u and v are written into + * u_vertices and v_vertices respectively. + */ +bool findloop_is_bridge( + struct findloopstate *pv, int u, int v, int *u_vertices, int *v_vertices); + /* * Helper function to sort an array. Differs from standard qsort in * that it takes a context parameter that is passed to the compare