void biconnectivity::init_handler(graph& G)
{
	if (add_edges) {
		dfs D;
		D.scan_whole_graph(true);
		D.check(G);
		D.run(G);

		roots_iterator it, end;
		it = D.roots_begin();
		end = D.roots_end();
		start = *(*it);
		++it;

		for (; it != end; ++it) {
			additional.push_back(G.new_edge(start, *(*it)));
		}

		first_child.init(G, node());
	}

	low_num.init(G);
	in_component.init(G);
	cut_count.init(G, 0);

	//
	// Detect self loops and hide them.
	// 

	assert(self_loops.empty());
	graph::edge_iterator eit = G.edges_begin(),
		eend = G.edges_end();

	while (eit != eend) {
		edge e = *eit;
		eit++;
		if (e.target() == e.source()) {
			self_loops.push_back(e);
			G.hide_edge(e);
		}
	}
}
void biconnectivity::after_recursive_call_handler(graph& G, edge& e, node& n)
{
	node curr = n.opposite(e);

	if (low_num[n] < low_num[curr]) {
		low_num[curr] = low_num[n];
	}

	if (low_num[n] >= dfs_num(curr)) {
		//
		// Component found
		// 

		if (store_comp) {
			component_iterator li = components.insert(
				components.end(),
				std::pair<nodes_t, edges_t>(nodes_t(), edges_t()));

			nodes_t& component = li->first;
			edges_t& co_edges = li->second;

			//
			// Nodes of biconnected component
			// 

			node tmp = node_stack.top();

			while (dfs_num(tmp) >= dfs_num(n)) {
				node_stack.pop();
				component.push_back(tmp);
				in_component[tmp] = li;
				if (node_stack.empty()) break;
				else tmp = node_stack.top();
			}

			component.push_back(curr);

			//
			// edges of biconnected component
			//

			edge ed = edge_stack.top();

			while ((dfs_num(ed.source()) >= dfs_num(n) &&
				dfs_num(ed.target()) >= dfs_num(n)) ||
				(dfs_num(ed.source()) == dfs_num(curr) &&
				dfs_num(ed.target()) >= dfs_num(n)) ||
				(dfs_num(ed.source()) >= dfs_num(n) &&
				dfs_num(ed.target()) == dfs_num(curr))) {
				edge_stack.pop();
				co_edges.push_back(ed);
				if (edge_stack.empty()) break;
				else ed = edge_stack.top();
			}
		}


		++num_of_components;

		//
		// curr is cut point; increase counter
		// 

		++cut_count[curr];

		if (add_edges) {
			node father = (*preds)[curr];
			node first = first_child[curr];

			if (father != node() && n == first) {
				additional.push_back(G.new_edge(father, first));
			}

			if (n != first) {
				additional.push_back(G.new_edge(n, first));
			}
		}

	}
}