//-----------------------------------------------------------------------------
#include <iostream.h>
#include <stdlib.h>
#include <LEDA/ugraph.h>
#include <LEDA/graph_gen.h>
#include <LEDA/node_array.h>
#include <LEDA/stack.h>
//-----------------------------------------------------------------------------
void BC(const ugraph &MyGraph);
void DoBC(const ugraph &MyGraph,node CurrentNode,node ParentNode,
node_array<int> &DFN,node_array<int> &LOW,stack<edge> &EdgeStack,
int NextDFN);
//-----------------------------------------------------------------------------
int main(int argc,char *argv[]) {

if (argc != 3) {
    cout << "Usage BCComponents <number of nodes> <number of edges>" << endl;
    exit(-1);
    }

int NumberOfNodes = atoi(argv[1]);
int NumberOfEdges = atoi(argv[2]);

ugraph MyGraph;

cout << "Creating random graph with " << NumberOfNodes << " nodes and "
     << NumberOfEdges << " edges" << endl;
random_simple_undirected_graph(MyGraph,NumberOfNodes,NumberOfEdges);
MyGraph.print();

BC(MyGraph);

return(0);
}
//-----------------------------------------------------------------------------
void BC(const ugraph &MyGraph) {

node_array<int> DFN(MyGraph,0);
node_array<int> LOW(MyGraph,0);
stack<edge> EdgeStack;

DoBC(MyGraph,MyGraph.first_node(),nil,DFN,LOW,EdgeStack,1);
}
//-----------------------------------------------------------------------------
void DoBC(const ugraph &MyGraph,node CurrentNode,node ParentNode,
node_array<int> &DFN,node_array<int> &LOW,stack<edge> &EdgeStack,
int NextDFN) {

edge AdjacentEdge,ComponentEdge;
node AdjacentNode;

//DEBUG cout << "Current node is ";
//DEBUG MyGraph.print_node(CurrentNode);
//DEBUG cout << " Parent node is ";
//DEBUG if (ParentNode == nil)
//DEBUG     cout << "non-existent";
//DEBUG else MyGraph.print_node(ParentNode);
//DEBUG cout << endl;

DFN[CurrentNode] = LOW[CurrentNode] = NextDFN++;

forall_adj_edges(AdjacentEdge,CurrentNode) {
    AdjacentNode = MyGraph.opposite(CurrentNode,AdjacentEdge);
    if (AdjacentNode != ParentNode && DFN[AdjacentNode] < DFN[CurrentNode])
        EdgeStack.push(AdjacentEdge);
    if (DFN[AdjacentNode] == 0) {
        DoBC(MyGraph,AdjacentNode,CurrentNode,DFN,LOW,EdgeStack,NextDFN);
        if (LOW[AdjacentNode] < LOW[CurrentNode])
            LOW[CurrentNode] = LOW[AdjacentNode];
        if (LOW[AdjacentNode] >= DFN[CurrentNode]) {
            cout << "New component :" << endl;
            do {
                ComponentEdge = EdgeStack.pop();
                MyGraph.print_edge(ComponentEdge);
                cout << " ";
                } while (AdjacentEdge != ComponentEdge);
            cout << endl;
            }
        }
    else if (AdjacentNode != ParentNode && 
DFN[AdjacentNode] < LOW[CurrentNode])
            LOW[CurrentNode] = DFN[AdjacentNode];
    }
}
//-----------------------------------------------------------------------------
