Second Best Minimum Spanning Tree

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 <bits/stdc++.h>using namespace std;  // used to implement union-find algorithmint parent[100005];  // to keep track of edges in MSTvector<int> present;  // to keep track of number of edges// in spanning trees other than the MSTint edg;  // a structure to represent a// weighted edge in graphstruct 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 edgesbool cmp(edge x, edge y){    return x.weight < y.weight;}  // initialising the array -// each vertex is its own parent// initiallyvoid initialise(int n){    // 1-indexed    for (int i = 1; i <= n; i++)        parent[i] = i;}  // Implementing the union-find algorithmint find(int x){    if (parent[x] == x)        return x;    return parent[x] = find(parent[x]);}  // Function to find the union// for the Minimum spanning Treeint 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 Treeint 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 Codeint 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;}
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.
Kruskal'sAlgorithm
LCA
Minimum Spanning Tree
MST
Algorithms
Graph
Tree
Graph
Tree
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
What is Hashing | A Complete Tutorial
Find if there is a path between two vertices in an undirected graph
How to Start Learning DSA?
Complete Roadmap To Learn DSA From Scratch
Types of Complexity Classes | P, NP, CoNP, NP hard and NP complete
Breadth First Search or BFS for a Graph
Depth First Search or DFS for a Graph
Dijkstra's shortest path algorithm | Greedy Algo-7
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Graph and its representations