# Second Best Minimum Spanning Tree

• Difficulty Level : Hard
• Last Updated : 23 Jul, 2021

Prerequisites Graph, Spanning tree, Disjoint Set (Union – Find).

A minimum spanning tree (MST) T, for a given graph G, spans over all vertices of a given graph and has minimum weight sum of all edges, out of all the possible spanning trees.

Second best MST, T’, is a spanning tree with the second minimum weight sum of all edges, out of all spanning trees of graph G.

T and T’ differ by only one edge replacement. So, we should find an edge enew which is not in T and replace it with an edge in T (say eold) such that T’ = T union {enew} – {eold} is a spanning tree and weight difference of (enew – eold) is minimum (enew, eold are edges in the graph G).

Using Kruskal’s Algorithm

• Use Kruskal’s algorithm to find MST T of graph G. Remove a single edge from it and replace it with another to obtain T’.
• Sort the edges in O(ElogE) time (E-no.of edges) and find MST using Kruskal’s algorithm in O(E) time (No.of edges in MST = V-1 where V = no.of vertices in the graph G).
• For each edge in MST, temporarily exclude it from the edge list (so that we cannot choose it).
• Then, try to find MST in O(E) using the remaining edges. (no need to sort again)
• Repeat the above for all edges in MST and take the best one. (with 2nd minimum weight sum). Thus, we obtained  T’ – second-best MST.
• Overall Time Complexity – O(ElogE + E +VE) = O(VE)

Below is the implementation of the above approach:

## C++

 `// C++ implementation to find the ` `// second best MST ` ` `  `#include ` `using` `namespace` `std; ` ` `  `// used to implement union-find algorithm ` `int` `parent[100005]; ` ` `  `// to keep track of edges in MST ` `vector<``int``> present; ` ` `  `// to keep track of number of edges ` `// in spanning trees other than the MST ` `int` `edg; ` ` `  `// a structure to represent a ` `// weighted edge in graph ` `struct` `edge { ` `    ``int` `src, dest, weight; ` `} edges[100005]; ` `// array edges is of type edge. ` ` `  `// Compare two edges according ` `// to their weights. ` `// Used in sort() for sorting ` `// an array of edges ` `bool` `cmp(edge x, edge y) ` `{ ` `    ``return` `x.weight < y.weight; ` `} ` ` `  `// initialising the array - ` `// each vertex is its own parent ` `// initially ` `void` `initialise(``int` `n) ` `{ ` `    ``// 1-indexed ` `    ``for` `(``int` `i = 1; i <= n; i++) ` `        ``parent[i] = i; ` `} ` ` `  `// Implementing the union-find algorithm ` `int` `find(``int` `x) ` `{ ` `    ``if` `(parent[x] == x) ` `        ``return` `x; ` `    ``return` `parent[x] = find(parent[x]); ` `} ` ` `  `// Function to find the union ` `// for the Minimum spanning Tree ` `int` `union1(``int` `i, ``int` `sum) ` `{ ` `    ``int` `x, y; ` `    ``x = find(edges[i].src); ` `    ``y = find(edges[i].dest); ` `    ``if` `(x != y) { ` ` `  `        ``// parent of x = y (LCA) - ` `        ``// both are edge connected ` `        ``parent[x] = y; ` ` `  `        ``// keeping track of edges in MST ` `        ``present.push_back(i); ` ` `  `        ``// finding sum of weights ` `        ``// of edges in MST ` `        ``sum += edges[i].weight; ` `    ``} ` `    ``return` `sum; ` `} ` ` `  `// Function to find the second ` `// best minimum spanning Tree ` `int` `union2(``int` `i, ``int` `sum) ` `{ ` `    ``int` `x, y; ` `    ``x = find(edges[i].src); ` `    ``y = find(edges[i].dest); ` `    ``if` `(x != y) { ` `        ``// parent of x = y (LCA) - ` `        ``// both are edge connected ` `        ``parent[x] = y; ` ` `  `        ``// sum of weights of edges ` `        ``// in spanning tree ` `        ``sum += edges[i].weight; ` `        ``edg++; ` `    ``} ` `    ``return` `sum; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``// V-> Number of vertices, ` `    ``// E-> Number of edges ` `    ``int` `V, E; ` `    ``V = 5; ` `    ``E = 8; ` ` `  `    ``// initialising the array to ` `    ``// be used for union-find ` `    ``initialise(V); ` ` `  `    ``// src, dest and weights can ` `    ``// also be taken from user as ` `    ``// input the following vectors ` `    ``// represent - source[0], ` `    ``// destination[0] are connected ` `    ``// by an edge with ` `    ``// weight[0] ` ` `  `    ``vector<``int``> source = { 1, 3, 2, 3, ` `                           ``2, 5, 1, 3 }; ` `    ``vector<``int``> destination = { 3, 4, 4, ` `                                ``2, 5, 4, 2, 5 }; ` `    ``vector<``int``> weights = { 75, 51, 19, ` `                            ``95, 42, 31, 9, 66 }; ` `    ``for` `(``int` `i = 0; i < E; i++) { ` `        ``edges[i].src = source[i]; ` `        ``edges[i].dest = destination[i]; ` `        ``edges[i].weight = weights[i]; ` `    ``} ` ` `  `    ``// sorting the array of edges ` `    ``// based on edge weights ` `    ``sort(edges, edges + E, cmp); ` ` `  `    ``int` `sum = 0; ` `    ``for` `(``int` `i = 0; i < E; i++) { ` `        ``sum = union1(i, sum); ` `    ``} ` ` `  `    ``// printing the cost of MST ` `    ``cout << ``"MST: "` `<< sum << ``"\n"``; ` ` `  `    ``// initialising cost of second best MST ` `    ``int` `sec_best_mst = INT_MAX; ` ` `  `    ``// setting the sum to zero again. ` `    ``sum = 0; ` `    ``int` `j; ` `    ``for` `(j = 0; j < present.size(); j++) { ` `        ``initialise(V); ` `        ``edg = 0; ` `        ``for` `(``int` `i = 0; i < E; i++) { ` ` `  `            ``// excluding one edge of ` `            ``// MST at a time ` `            ``// and forming spanning tree ` `            ``// with remaining ` `            ``// edges ` `            ``if` `(i == present[j]) ` `                ``continue``; ` `            ``sum = union2(i, sum); ` `        ``} ` `        ``// checking if number of edges = V-1 or not ` `        ``// since number of edges in a spanning tree of ` `        ``// graph with V vertices is (V-1) ` `        ``if` `(edg != V - 1) { ` `            ``sum = 0; ` `            ``continue``; ` `        ``} ` ` `  `        ``// storing the minimum sum ` `        ``// in sec_best_mst ` `        ``if` `(sec_best_mst > sum) ` `            ``sec_best_mst = sum; ` `        ``sum = 0; ` `    ``} ` ` `  `    ``// printing the cost of second best MST ` `    ``cout << ``"Second Best MST: "` `         ``<< sec_best_mst << ``"\n"``; ` `    ``return` `0; ` `}`

Output

```MST: 110
Second Best MST: 121
```

Time Complexity – O(VE) where V – number of vertices in the input graph, E – number of edges in the input graph.

My Personal Notes arrow_drop_up
Related Articles