# Minimum labelled node to be removed from undirected Graph such that there is no cycle

Given an **undirected graph** of **N** nodes labelled from 1 to N, the task is to find the minimum labelled node that should be removed from the graph such that the resulting graph has no cycle.

**Note:** If the initial graph has no cycle, i.e no node needs to be removed, print -1.

**Examples:**

Input:N = 5, edges[][] = {{5, 1}, {5, 2}, {1, 2}, {2, 3}, {2, 4}}

Output:1

Explanation:

If node 1 is removed, the resultant graph has no cycle. Similarly, the cycle can be avoided by removing node 2 also.

Since we have to find the minimum labelled node, the answer is 1.

Input:N = 5, edges[][] = {{4, 5}, {4, 1}, {4, 2}, {4, 3}, {5, 1}, {5, 2}}

Output:4

**Naive Approach:** The naive approach for this problem would be to remove each vertex individually and check whether the resulting graph has a cycle or not. The time complexity for this approach is quadratic.

**Efficient Approach:** The idea is to apply depth-first search on the given graph and observing the dfs tree formed.

- A Back Edge is referred to as the edge that is not part of the constructed DFS tree and is an edge between some node v and one of the ancestors of v.
- Clearly all those edges of the graph which are not a part of the DFS tree are back edges.
- If there are no back edges in the graph, then the graph has no cycle. So, the answer will be
**-1**in this case.

If there are back edges in the graph, then we need to find the minimum edge. In order to do this, we need to check if the cycle is removed on removing a specific edge from the graph. Therefore, let **v** be a vertex which we are currently checking. Therefore, the **following conditions must be followed by vertex v** such that on removing, it would lead to no cycle:

**v**must lie on the tree path connecting the endpoints of each back edge in the graph.

**Proof:**Suppose there exists some back edge x-y, such that v doesn’t lie on the tree path. If we remove v, we would still be able to traverse from x to y, and back to x via the back edge, indicating that the cycle is not removed.- The subtree of v must have at-most one back edge to any ancestor of v.

**Proof:**Let the subtree S has to back edges w-x and y-z such that w and y are in S and x and z are ancestors of v. If we remove v, clearly a cycle still exists consisting of the path between w to y, the path from x to z and the two back edges w-x and y-z, i.e. cycle is not removed.

Therefore, the idea is to keep a track of back edges, and an indicator for the number of back edges in the subtree of a node to any of its ancestors. To keep a track of back edges we will use a modified DFS graph colouring algorithm.

In order to check if the subtree v has at-most one back edge to any ancestor of v or not, we implement dfs such that it returns the depth of two highest edges from the subtree of v. We maintain an array where every index ‘i’ in the array stores if the condition 2 from the above is satisfied by the node ‘i’ or not. Similarly, two arrays are implemented, one for the child and another for the parent to see if the node v lies on the tree path connecting the endpoints.

Below is the implementation of the above approach:

`// C++ implementation to find the ` `// minimum labelled node to be ` `// removed such that there is no ` `// cycle in the undirected graph ` ` ` `#include <bits/stdc++.h> ` ` ` `using` `namespace` `std; ` ` ` `const` `int` `MAX = 100005; ` ` ` `int` `totBackEdges; ` `int` `countAdj[MAX], small[MAX]; ` ` ` `// Variables to store if a node V has ` `// at-most one back edge and store the ` `// depth of the node for the edge ` `int` `isPossible[MAX], depth[MAX]; ` ` ` `vector<` `int` `> adj[MAX]; ` `int` `vis[MAX]; ` ` ` `// Function to swap the pairs of the graph ` `void` `change(pair<` `int` `, ` `int` `>& p, ` `int` `x) ` `{ ` ` ` `// If the second value is ` ` ` `// greater than x ` ` ` `if` `(p.second > x) ` ` ` `p.second = x; ` ` ` ` ` `// Put the pair in the ascending ` ` ` `// order internally ` ` ` `if` `(p.first > p.second) ` ` ` `swap(p.first, p.second); ` `} ` ` ` `// Function to perform the DFS ` `pair<` `int` `, ` `int` `> dfs(` `int` `v, ` `int` `p = -1, ` `int` `de = 0) ` `{ ` ` ` `// Initialise with the large value ` ` ` `pair<` `int` `, ` `int` `> answer(100000000, 100000000); ` ` ` ` ` `// Storing the depth of this vertex ` ` ` `depth[v] = de; ` ` ` ` ` `// Mark the vertex as visited ` ` ` `vis[v] = 1; ` ` ` `isPossible[v] = 1; ` ` ` ` ` `// Iterating through the graph ` ` ` `for` `(` `int` `u : adj[v]) { ` ` ` ` ` `// If the node is a child node ` ` ` `if` `(u ^ p) { ` ` ` ` ` `// If the child node is unvisited ` ` ` `if` `(!vis[u]) { ` ` ` ` ` `// Move to the child and increase ` ` ` `// the depth ` ` ` `auto` `x = dfs(u, v, de + 1); ` ` ` ` ` `// increase according to algorithm ` ` ` `small[v] += small[u]; ` ` ` ` ` `change(answer, x.second); ` ` ` `change(answer, x.first); ` ` ` ` ` `// If the node is not having ` ` ` `// exactly K backedges ` ` ` `if` `(x.second < de) ` ` ` `isPossible[v] = 0; ` ` ` `} ` ` ` ` ` `// If the child is already visited ` ` ` `// and in current dfs ` ` ` `// (because colour is 1) ` ` ` `// then this is a back edge ` ` ` `else` `if` `(vis[u] == 1) { ` ` ` `totBackEdges++; ` ` ` ` ` `// Increase the countAdj values ` ` ` `countAdj[v]++; ` ` ` `countAdj[u]++; ` ` ` `small[p]++; ` ` ` `small[u]--; ` ` ` `change(answer, depth[u]); ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` ` ` `// Colour this vertex 2 as ` ` ` `// we are exiting out of ` ` ` `// dfs for this node ` ` ` `vis[v] = 2; ` ` ` `return` `answer; ` `} ` ` ` `// Function to find the minimum labelled ` `// node to be removed such that ` `// there is no cycle in the undirected graph ` `int` `minNodetoRemove( ` ` ` `int` `n, ` ` ` `vector<pair<` `int` `, ` `int` `> > edges) ` `{ ` ` ` ` ` `// Construct the graph ` ` ` `for` `(` `int` `i = 0; i < edges.size(); i++) { ` ` ` `adj[edges[i].first] ` ` ` `.push_back(edges[i].second); ` ` ` `adj[edges[i].second] ` ` ` `.push_back(edges[i].first); ` ` ` `} ` ` ` ` ` `// Mark visited as false for each node ` ` ` `memset` `(vis, 0, ` `sizeof` `(vis)); ` ` ` ` ` `totBackEdges = 0; ` ` ` ` ` `// Apply dfs on all unmarked nodes ` ` ` `for` `(` `int` `v = 1; v <= n; v++) { ` ` ` `if` `(!vis[v]) ` ` ` `dfs(v); ` ` ` `} ` ` ` ` ` `// If no backedges in the initial graph ` ` ` `// this means that there is no cycle ` ` ` `// So, return -1 ` ` ` `if` `(totBackEdges == 0) ` ` ` `return` `-1; ` ` ` ` ` `int` `node = -1; ` ` ` ` ` `// Iterate through the vertices and ` ` ` `// return the first node that ` ` ` `// satisfies the condition ` ` ` `for` `(` `int` `v = 1; v <= n; v++) { ` ` ` ` ` `// Check whether the count sum of ` ` ` `// small[v] and count is the same as ` ` ` `// the total back edges and ` ` ` `// if the vertex v can be removed ` ` ` `if` `(countAdj[v] + small[v] ` ` ` `== totBackEdges ` ` ` `&& isPossible[v]) { ` ` ` `node = v; ` ` ` `} ` ` ` `if` `(node != -1) ` ` ` `break` `; ` ` ` `} ` ` ` ` ` `return` `node; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `int` `N = 5; ` ` ` `vector<pair<` `int` `, ` `int` `> > edges; ` ` ` `edges.push_back(make_pair(5, 1)); ` ` ` `edges.push_back(make_pair(5, 2)); ` ` ` `edges.push_back(make_pair(1, 2)); ` ` ` `edges.push_back(make_pair(2, 3)); ` ` ` `edges.push_back(make_pair(2, 4)); ` ` ` ` ` `cout << minNodetoRemove(N, edges); ` `} ` |

*chevron_right*

*filter_none*

**Output:**

1

**Time Comlexity:** *O(N + M)*, where N is the number of nodes and M is the number of edges.

## Recommended Posts:

- Find minimum weight cycle in an undirected graph
- Detect cycle in an undirected graph
- Detect cycle in an undirected graph using BFS
- Shortest cycle in an undirected unweighted graph
- Check if there is a cycle with odd weight sum in an undirected graph
- Number of single cycle components in an undirected graph
- Disjoint Set (Or Union-Find) | Set 1 (Detect Cycle in an Undirected Graph)
- Kth largest node among all directly connected nodes to the given node in an undirected graph
- Sum of the minimum elements in all connected components of an undirected graph
- Minimum edges to be added in a directed graph so that any node can be reachable from a given node
- Convert the undirected graph into directed graph such that there is no path of length greater than 1
- Detect cycle in the graph using degrees of nodes of graph
- Minimum value of distance of farthest node in a Graph
- Convert undirected connected graph to strongly connected directed graph
- Clone an Undirected Graph
- Find k-cores of an undirected graph
- Number of Triangles in an Undirected Graph
- Sum of degrees of all nodes of a undirected graph
- Print all the cycles in an undirected graph
- Eulerian Path in undirected graph

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.