#include "puzzles.h"
struct findloopstate {
- int parent, child, sibling;
+ int parent, child, sibling, component_root;
bool visited;
int index, minindex, maxindex;
int minreachable, maxreachable;
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)
{
*/
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;
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;
}
*/
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