UNPKG

react-planner

Version:

react-planner is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.

151 lines (126 loc) 4.32 kB
//JS porting of this code http://www.geeksforgeeks.org/biconnected-components/ function create_array(length) { let array = []; for (let i = 0; i < length; ++i) { array.push([]); } return array; } class Edge { constructor(u, v) { this.u = u; this.v = v; } } class Graph { constructor(v) { this.count = 0; // count is number of biconnected components this.subgraphs = []; //biconnected components this.time = 0; // time is used to find discovery times this.V = v; // No. of vertices this.E = 0; // No. of Edges this.adj = []; // Adjacency List this.adj = create_array(v); } //Function to add an edge into the graph addEdge(v, w) { this.adj[v].push(w); this.E++; } // A recursive function that finds and prints strongly connected // components using DFS traversal // u --> The vertex to be visited next // disc[] --> Stores discovery times of visited vertices // low[] -- >> earliest visited vertex (the vertex with minimum // discovery time) that can be reached from subtree // rooted with current vertex // *st -- >> To store visited edges // // A recursive function that finds and prints strongly connected // components using DFS traversal // u --> The vertex to be visited next // disc[] --> Stores discovery times of visited vertices // low[] -- >> earliest visited vertex (the vertex with minimum // discovery time) that can be reached from subtree // rooted with current vertex // *st -- >> To store visited edges _BCCUtil(u, disc, low, st, parent) { // Initialize discovery time and low value disc[u] = low[u] = ++this.time; this.children = 0; // Go through all vertices adjacent to this // v is current adjacent of 'u' this.adj[u].forEach(v => { // If v is not visited yet, then recur for it if (disc[v] == -1) { this.children++; parent[v] = u; // store the edge in stack st.push(new Edge(u, v)); this._BCCUtil(v, disc, low, st, parent); // Check if the subtree rooted with 'v' has a // connection to one of the ancestors of 'u' // Case 1 -- per Strongly Connected Components Article if (low[u] > low[v]) low[u] = low[v]; // If u is an articulation point, // pop all edges from stack till u -- v if ((disc[u] == 1 && this.children > 1) || (disc[u] > 1 && low[v] >= disc[u])) { let subgraph = []; while (st[st.length - 1].u != u || st[st.length - 1].v != v) { subgraph.push(st[st.length - 1]); //console.log(st[st.length - 1].u + "--" + st[st.length - 1].v + " "); st.splice(st.length - 1, 1); } subgraph.push(st[st.length - 1]); //console.log(st[st.length - 1].u + "--" + st[st.length - 1].v + " "); this.subgraphs.push(subgraph); subgraph = []; //console.log() st.splice(st.length - 1, 1); this.count++; } } // Update low value of 'u' only of 'v' is still in stack // (i.e. it's a back edge, not cross edge). // Case 2 -- per Strongly Connected Components Article else if (v != parent[u] && disc[v] < low[u]) { if (low[u] > disc[v]) low[u] = disc[v]; st.push(new Edge(u, v)); } }) } BCC() { let V = this.V; let disc = create_array(V); let low = create_array(V); let parent = create_array(V); let st = []; // Initialize disc and low, and parent arrays for (let i = 0; i < V; i++) { disc[i] = -1; low[i] = -1; parent[i] = -1; } for (let i = 0; i < V; i++) { if (disc[i] == -1) this._BCCUtil(i, disc, low, st, parent); let j = 0; // If stack is not empty, pop all edges from stack let subgraph = []; while (st.length > 0) { j = 1; subgraph.push(st[st.length - 1]); //console.log(st[st.length - 1].u + "--" + st[st.length - 1].v + " "); st.splice(st.length - 1, 1); } if (j == 1) { this.subgraphs.push(subgraph); subgraph = []; //console.log(); this.count++; } } } } module.exports = Graph;