Open In App

# Check if an edge is a part of any Minimum Spanning Tree

Given a connected undirected weighted graph in the form of a 2D array where each row is of the type [start node, end node, weight] describing an edge, and also two integers (A, B). Return if the edge formed between (A, B) is a part of any of the Minimum Spanning Tree (MST) of the graph.

Minimum Spanning Tree (MST): This is a special subgraph of the graph, such that each and every vertex is connected and the overall sum of the weights of the edges of this subgraph is as minimum as possible. A graph can have multiple minimum spanning trees.

Examples:

Input: graph = [[0 ,1, 20] , [0 , 2 , 5] , [ 0, 3, 10 ] , [ 2, 3, 10]], A = 2, B = 3
Output:  True
Explanation : 2 minimum spanning trees with can be generated which will have weight 35. The connections of the trees are
1st: [ (0,1) , (0,3) , (0,2)] => 20 + 10 + 5 = 35
2nd: [ ( 0 , 1) , ( 0 , 2 ) , ( 2 , 3) ] => 20 + 5 + 10 = 35
As it can be seen , the edge ( 2, 3) is present in second MST.

The graph is shown in image:

Input: graph = [[0 ,1, 20] , [0 , 2 , 5] , [ 0, 3, 10 ] , [ 2, 3, 20]], A = 2, B = 3
Output: False
Explanation: Only 1 minimum spanning trees with weight 35 can be generated,
but edge (2, 3) is not included.
[(0,1) , (0,3) , (0,2)] => 20 + 10 + 5 = 35

The graph is given in the image

Approach : Kruskal Algorithm and Prim’s Algorithm are the two most used algorithms that can be used to find MST of any graph. In this article, the solution is based on the Kruskal algorithm. Follow the steps mentioned below to solve the problem using this approach:

1. Find the minimum spanning tree cost of the entire graph, using the Kruskal algorithm.
2. As the inclusion of the edge (A, B) in the MST is being checked, include this edge first in the minimum spanning tree and then include other edges subsequently.
3. Finally check if the cost is the same for both the spanning trees including the edge(A, B) and the calculated weight of the MST.
4. If cost is the same, then edge (A, B) is a part of some MST of the graph otherwise it is not.

Below is the implementation of the above approach:

## C++

 `#include ``using` `namespace` `std;` `// Class to implement disjoint set union``class` `dsu {``public``:``    ``unordered_map<``int``, ``int``> parent;``    ``unordered_map<``int``, ``int``> rank;` `    ``// Function to find parent of a node``    ``int` `find(``int` `x)``    ``{``        ``if` `(parent.count(x) == 0) {``            ``rank[x] = 1;``            ``parent[x] = x;``        ``}``        ``if` `(parent[x] != x) {``            ``parent[x] = find(parent[x]);``        ``}``        ``return` `parent[x];``    ``}` `    ``// Function to perform union``    ``bool` `unite(``int` `u, ``int` `v)``    ``{``        ``int` `p1 = find(u), p2 = find(v);` `        ``// If do not belong to same set``        ``if` `(p1 != p2) {``            ``if` `(rank[p1] < rank[p2]) {``                ``parent[p1] = p2;``            ``}``            ``else` `if` `(rank[p1] > rank[p2]) {``                ``parent[p2] = p1;``            ``}``            ``else` `{``                ``parent[p2] = p1;``                ``rank[p1] += 1;``            ``}``            ``return` `true``;``        ``}` `        ``// Belong to same set``        ``else` `{``            ``return` `false``;``        ``}``    ``}``};` `class` `Solution {``public``:``    ``// Find the MST weight``    ``int` `kruskal(``bool` `include, vector >& edges,``                ``int` `a, ``int` `b)``    ``{``        ``dsu obj;``        ``int` `total = 0;` `        ``// If include is True, then include edge (a, b)``        ``// first``        ``if` `(include) {``            ``for` `(``auto` `edge : edges) {``                ``int` `u = edge[0], v = edge[1], wt = edge[2];` `                ``// As graph is undirected so (a, b) or (b,``                ``// a) is same If found break the for loop``                ``if` `((u == a && v == b)``                    ``|| (u == b && v == a)) {``                    ``bool` `val = obj.unite(a, b);``                    ``total += wt;``                    ``break``;``                ``}``            ``}``        ``}` `        ``// Go on adding edge to the disjoint set``        ``for` `(``auto` `edge : edges) {``            ``int` `u = edge[0], v = edge[1], wt = edge[2];` `            ``// Nodes (u, v) not belong to same set include``            ``// it``            ``if` `(obj.unite(u, v)) {``                ``total += wt;``            ``}``        ``}` `        ``// Finally return total weight of MST``        ``return` `total;``    ``}` `    ``// Function to find if edge (a, b) is part of any MST``    ``bool` `solve(vector >& edges, ``int` `a, ``int` `b)``    ``{``        ``// Sort edges according to weight in ascending order``        ``sort(edges.begin(), edges.end(),``             ``[](vector<``int``> a, vector<``int``> b) {``                 ``return` `a[2] < b[2];``             ``});` `        ``// Not included edge (a, b)``        ``int` `overall = kruskal(``false``, edges, a, b);` `        ``// Find mst with edge (a, b) included``        ``int` `inc = kruskal(``true``, edges, a, b);` `        ``// Finally return True if same else False``        ``return` `inc == overall;``    ``}``};``int` `main()``{``    ``Solution obj;``    ``vector > graph = { { 0, 1, 20 },``                                   ``{ 0, 2, 5 },``                                   ``{ 0, 3, 10 },``                                   ``{ 2, 3, 10 } };``    ``int` `A = 2, B = 3;``    ``bool` `val = obj.solve(graph, A, B);``    ``if` `(val) {``        ``cout << ``"True"` `<< endl;``    ``}``    ``else` `{``        ``cout << ``"False"` `<< endl;``    ``}``    ``return` `0;``}` `// This code is contributed by lokeshpotta20.`

## Java

 `// Java program to implement above approach` `import` `java.io.*;``import` `java.util.*;` `// Class to implement disjoint set union``class` `DSU {``    ``Map parent = ``new` `HashMap<>();``    ``Map rank = ``new` `HashMap<>();` `    ``// Function to find parent of a node``    ``int` `find(``int` `x)``    ``{``        ``if` `(!parent.containsKey(x)) {``            ``rank.put(x, ``1``);``            ``parent.put(x, x);``        ``}``        ``if` `(parent.get(x) != x) {``            ``parent.put(x, find(parent.get(x)));``        ``}``        ``return` `parent.get(x);``    ``}` `    ``// Function to perform union``    ``boolean` `unite(``int` `u, ``int` `v)``    ``{``        ``int` `p1 = find(u), p2 = find(v);` `        ``// If do not belong to same set``        ``if` `(p1 != p2) {``            ``if` `(rank.get(p1) < rank.get(p2)) {``                ``parent.put(p1, p2);``            ``}``            ``else` `if` `(rank.get(p1) > rank.get(p2)) {``                ``parent.put(p2, p1);``            ``}``            ``else` `{``                ``parent.put(p2, p1);``                ``rank.put(p1, rank.get(p1) + ``1``);``            ``}``            ``return` `true``;``        ``}` `        ``// Belong to same set``        ``else` `{``            ``return` `false``;``        ``}``    ``}``}` `class` `Solution {` `    ``// Find the MST weight``    ``int` `kruskal(``boolean` `include, List > edges,``                ``int` `a, ``int` `b)``    ``{``        ``DSU obj = ``new` `DSU();``        ``int` `total = ``0``;``        ``// If include is True, then include edge (a, b)``        ``// first``        ``if` `(include) {``            ``for` `(List edge : edges) {``                ``int` `u = edge.get(``0``), v = edge.get(``1``),``                    ``wt = edge.get(``2``);` `                ``// As graph is undirected so (a, b) or (b,``                ``// a) is same If found break the for loop``                ``if` `((u == a && v == b)``                    ``|| (u == b && v == a)) {``                    ``boolean` `val = obj.unite(a, b);``                    ``total += wt;``                    ``break``;``                ``}``            ``}``        ``}` `        ``// Go on adding edge to the disjoint set``        ``for` `(List edge : edges) {``            ``int` `u = edge.get(``0``), v = edge.get(``1``),``                ``wt = edge.get(``2``);` `            ``// Nodes (u, v) not belong to same set include``            ``// it``            ``if` `(obj.unite(u, v)) {``                ``total += wt;``            ``}``        ``}` `        ``// Finally return total weight of MST``        ``return` `total;``    ``}` `    ``// Function to find if edge (a, b) is part of any MST``    ``boolean` `solve(List > edges, ``int` `a, ``int` `b)``    ``{``        ``// Sort edges according to weight in ascending order``        ``Collections.sort(``            ``edges, ``new` `Comparator >() {``                ``@Override``                ``public` `int` `compare(List a,``                                   ``List b)``                ``{``                    ``return` `a.get(``2``) - b.get(``2``);``                ``}``            ``});` `        ``// Not included edge (a, b)``        ``int` `overall = kruskal(``false``, edges, a, b);` `        ``// Find mst with edge (a, b) included``        ``int` `inc = kruskal(``true``, edges, a, b);` `        ``// Finally return true if same else false``        ``return` `inc == overall;``    ``}``}` `class` `GFG {``    ``public` `static` `void` `main(String[] args)``    ``{``        ``Solution obj = ``new` `Solution();``        ``List > graph = Arrays.asList(``            ``Arrays.asList(``0``, ``1``, ``20``), Arrays.asList(``0``, ``2``, ``5``),``            ``Arrays.asList(``0``, ``3``, ``10``),``            ``Arrays.asList(``2``, ``3``, ``10``));``        ``int` `A = ``2``, B = ``3``;``        ``boolean` `val = obj.solve(graph, A, B);``        ``if` `(val) {``            ``System.out.println(``"True"``);``        ``}``        ``else` `{``            ``System.out.println(``"False"``);``        ``}``    ``}``}` `// This code is contributed by karthik.`

## Python3

 `# Python program to implement above approach` `# Class to implement disjoint set union``class` `dsu:``    ``def` `__init__(``self``):``        ``self``.parent ``=` `{}``        ``self``.rank ``=` `{}` `    ``# Function to find parent of a node``    ``def` `find(``self``, x):``        ``if` `(x ``not` `in` `self``.parent):``            ``self``.rank[x] ``=` `1``            ``self``.parent[x] ``=` `x``        ``if` `(``self``.parent[x] !``=` `x):``            ``self``.parent[x] ``=` `\``                ``self``.find(``self``.parent[x])``        ``return` `(``self``.parent[x])` `    ``# Function to perform union``    ``def` `union(``self``, u, v):``        ``p1 ``=` `self``.find(u)``        ``p2 ``=` `self``.find(v)` `        ``# If do not belong to same set``        ``if` `(p1 !``=` `p2):``            ``if` `(``self``.rank[p1]``                    ``< ``self``.rank[p2]):``                ``self``.parent[p1] ``=` `p2` `            ``elif``(``self``.rank[p1]``                 ``> ``self``.rank[p1]):``                ``self``.parent[p2] ``=` `p1``            ``else``:``                ``self``.parent[p2] ``=` `p1``                ``self``.rank[p1] ``+``=` `1``            ``return` `(``True``)` `        ``# Belong to same set``        ``else``:``            ``return` `False`  `class` `Solution:` `    ``# Find the MST weight``    ``def` `kruskal(``self``, include, edges, a, b):``        ``obj ``=` `dsu()``        ``total ``=` `0` `        ``# If include is True , then include``        ``# edge (a,b) first``        ``if` `(include):``            ``for` `(u, v, wt) ``in` `edges:` `                ``# As graph is undirected so``                ``# (a,b) or (b,a) is same``                ``# If found break the for loop``                ``if` `(u, v) ``=``=` `(a, b) ``or` `\``                        ``(b, a) ``=``=` `(u, v):``                    ``val ``=` `obj.union(a, b)``                    ``total ``+``=` `wt``                    ``break` `        ``# Go on adding edge to the disjoint set``        ``for` `(u, v, wt) ``in` `edges:` `            ``# Nodes (u,v) not belong to``            ``# same set include it``            ``if` `(obj.union(u, v)):``                ``total ``+``=` `wt` `        ``# Finally return total weight of MST``        ``return` `(total)` `    ``# Function to find if edge (a, b)``    ``# is part of any MST``    ``def` `solve(``self``, edges, a, b):` `        ``# Sort edges according to weight``        ``# in ascending order``        ``edges.sort(key``=``lambda` `it: it[``2``])` `        ``# Not included edge (a,b)``        ``overall ``=` `self``.kruskal(``False``,``                               ``edges, a, b)` `        ``# Find mst with edge (a,b) included``        ``inc ``=` `self``.kruskal(``True``,``                           ``edges, a, b)` `        ``# Finally return True if same``        ``# else False``        ``if` `(inc ``=``=` `overall):``            ``return` `(``True``)``        ``else``:``            ``return` `(``False``)` `# Driver code``if` `__name__ ``=``=` `"__main__"``:``    ``obj ``=` `Solution()``    ``graph ``=` `[[``0``, ``1``, ``20``], [``0``, ``2``, ``5``],``             ``[``0``, ``3``, ``10``], [``2``, ``3``, ``10``]]``    ``A, B ``=` `2``, ``3``    ``val ``=` `obj.solve(graph, A, B)``    ``if` `(val):``        ``print``(``"True"``)``    ``else``:``        ``print``(``"False"``)`

## C#

 `// C# program to implement above approach``using` `System;``using` `System.Collections.Generic;``using` `System.Linq;` `// Class to implement disjoint set union``public` `class` `dsu {``  ``Dictionary<``int``, ``int``> parent``    ``= ``new` `Dictionary<``int``, ``int``>();``  ``Dictionary<``int``, ``int``> rank = ``new` `Dictionary<``int``, ``int``>();` `  ``// Function to find parent of a node``  ``public` `int` `Find(``int` `x)``  ``{``    ``if` `(!parent.ContainsKey(x)) {``      ``rank[x] = 1;``      ``parent[x] = x;``    ``}``    ``if` `(parent[x] != x) {``      ``parent[x] = Find(parent[x]);``    ``}``    ``return` `parent[x];``  ``}` `  ``// Function to perform union``  ``public` `bool` `Unite(``int` `u, ``int` `v)``  ``{``    ``int` `p1 = Find(u), p2 = Find(v);` `    ``// If do not belong to same set``    ``if` `(p1 != p2) {``      ``if` `(rank[p1] < rank[p2]) {``        ``parent[p1] = p2;``      ``}``      ``else` `if` `(rank[p1] > rank[p2]) {``        ``parent[p2] = p1;``      ``}``      ``else` `{``        ``parent[p2] = p1;``        ``rank[p1] += 1;``      ``}``      ``return` `true``;``    ``}` `    ``// Belong to same set``    ``else` `{``      ``return` `false``;``    ``}``  ``}``}` `public` `class` `Solution {``  ``// Find the MST weight``  ``int` `Kruskal(``bool` `include, List > edges, ``int` `x,``              ``int` `y)``  ``{``    ``dsu obj = ``new` `dsu();``    ``int` `total = 0;` `    ``// If include is True, then include edge (a, b)``    ``// first``    ``if` `(include) {``      ``foreach``(``var` `edge ``in` `edges)``      ``{``        ``int` `u = edge[0], v = edge[1], wt = edge[2];` `        ``// As graph is undirected so (a, b) or (b,``        ``// a) is same If found break the for loop``        ``if` `((u == x && v == y)``            ``|| (u == y && v == x)) {``          ``if` `(obj.Unite(x, y)) {``            ``total += wt;``            ``break``;``          ``}``        ``}``      ``}``    ``}` `    ``// Go on adding edge to the disjoint set``    ``foreach``(``var` `edge ``in` `edges)``    ``{``      ``int` `u = edge[0], v = edge[1], wt = edge[2];` `      ``// Nodes (u, v) not belong to same set include``      ``// it``      ``if` `(obj.Unite(u, v)) {``        ``total += wt;``      ``}``    ``}` `    ``// Finally return total weight of MST``    ``return` `total;``  ``}` `  ``// Function to find if edge (a, b) is part of any MST``  ``public` `bool` `Solve(List > edges, ``int` `x, ``int` `y)``  ``{``    ``// Sort edges according to weight in ascending order``    ``edges.Sort((a, b) => a[2] - b[2]);` `    ``// Not included edge (a, b)``    ``int` `overall = Kruskal(``false``, edges, x, y);` `    ``// Find mst with edge (a, b) included``    ``int` `inc = Kruskal(``true``, edges, x, y);` `    ``// Finally return true if same else false``    ``return` `inc == overall;``  ``}``}` `public` `class` `GFG {` `  ``static` `public` `void` `Main()``  ``{` `    ``// Code``    ``Solution obj = ``new` `Solution();``    ``List > graph = ``new` `List >{``      ``new` `List<``int``>{ 0, 1, 20 },``      ``new` `List<``int``>{ 0, 2, 5 },``      ``new` `List<``int``>{ 0, 3, 10 },``      ``new` `List<``int``>{ 2, 3, 10 }``    ``};``    ``int` `A = 2, B = 3;``    ``bool` `val = obj.Solve(graph, A, B);``    ``if` `(val) {``      ``Console.WriteLine(``"True"``);``    ``}``    ``else` `{``      ``Console.WriteLine(``"False"``);``    ``}``  ``}``}` `// This code is contributed by sankar.`

## Javascript

 `// Class to implement disjoint set union``class DSU {``    ``constructor() {``        ``this``.parent = {};``        ``this``.rank = {};``    ``}`` ``// Function to find parent of a node``    ``find(x) {``        ``if` `(!(x ``in` `this``.parent)) {``            ``this``.rank[x] = 1;``            ``this``.parent[x] = x;``        ``}``        ``if` `(``this``.parent[x] !== x) {``            ``this``.parent[x] = ``this``.find(``this``.parent[x]);``        ``}``        ``return` `this``.parent[x];``    ``}`` ``// Function to perform union``    ``union(u, v) {``        ``let p1 = ``this``.find(u);``        ``let p2 = ``this``.find(v);``        ``if` `(p1 !== p2) {``        ``// If do not belong to same set``            ``if` `(``this``.rank[p1] < ``this``.rank[p2]) {``                ``this``.parent[p1] = p2;``            ``} ``else` `if` `(``this``.rank[p1] > ``this``.rank[p1]) {``                ``this``.parent[p2] = p1;``            ``} ``else` `{``                ``this``.parent[p2] = p1;``                ``this``.rank[p1] += 1;``            ``}``            ``return` `true``;``        ``} ``else` `{``            ``return` `false``;``        ``}``    ``}``}` `class Solution {`` ``// Find the MST weight``    ``kruskal(include, edges, a, b) {``        ``let obj = ``new` `DSU();``        ``let total = 0;``        ``if` `(include) {``            ``for` `(let i = 0; i < edges.length; i++) {``                ``let [u, v, wt] = edges[i];``                ``if` `((u === a && v === b) || (b === a && u === v)) {``                    ``let val = obj.union(a, b);``                    ``total += wt;``                    ``break``;``                ``}``            ``}``        ``}``        ``for` `(let i = 0; i < edges.length; i++) {``            ``let [u, v, wt] = edges[i];``            ``if` `(obj.union(u, v)) {``                ``total += wt;``            ``}``        ``}``        ``return` `total;``    ``}` `    ``solve(edges, a, b) {``     ``// As graph is undirected so (a, b) or (b,``                ``// a) is same If found break the for loop``        ``edges.sort((a, b) => a[2] - b[2]);``        ``let overall = ``this``.kruskal(``false``, edges, a, b);``        ``let inc = ``this``.kruskal(``true``, edges, a, b);``        ``return` `inc === overall;``    ``}``}` `let obj = ``new` `Solution();``let graph = [[0, 1, 20], [0, 2, 5], [0, 3, 10], [2, 3, 10]];``let A = 2, B = 3;``let val = obj.solve(graph, A, B);``if` `(val) {``    ``console.log(``"True"``);``} ``else` `{`` ``// Finally return True if same else False``    ``console.log(``"False"``);``}`

Output

`True`

Time Complexity: O(E * logV). where E is the number of edges and V is the number of vertices.
Auxiliary Space: O(V)