Segundo mejor árbol de expansión mínimo

Requisitos previos : gráfico , árbol de expansión , conjunto disjunto (unión: búsqueda) .

Un árbol de expansión mínimo (MST) T , para un gráfico G dado, abarca todos los vértices de un gráfico dado y tiene una suma de peso mínima de todos los bordes, de todos los árboles de expansión posibles. 

El segundo mejor MST, T’ , es un árbol de expansión con la segunda suma de peso mínimo de todos los bordes, de todos los árboles de expansión del gráfico G.

T y T’ difieren en un solo reemplazo de borde. Entonces, deberíamos encontrar una arista e nueva que no esté en T y reemplazarla con una arista en T (digamos e antigua ) tal que T’ = T unión {e nueva } – {e antigua } es un árbol de expansión y diferencia de peso de (e new – e old ) es mínimo (e new , e old son aristas en el gráfico G).

Usando el Algoritmo de Kruskal

  • Use el algoritmo de Kruskal para encontrar MST T del gráfico G. Quite un solo borde y reemplácelo con otro para obtener T’.
  • Ordene las aristas en el tiempo O(ElogE) (E-nº de aristas) y encuentre MST usando el algoritmo de Kruskal en el tiempo O(E) (Nº de aristas en MST = V-1 donde V = nº de vértices en el gráfico GRAMO).
  • Para cada borde en MST, exclúyalo temporalmente de la lista de bordes (para que no podamos elegirlo).
  • Luego, intente encontrar MST en O(E) usando los bordes restantes. (no es necesario ordenar de nuevo)
  • Repita lo anterior para todos los bordes en MST y tome el mejor. (con 2ª suma de peso mínimo). Así, obtuvimos T’ – segundo mejor MST.
  • Complejidad total del tiempo – O(ElogE + E +VE) = O(VE)

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ implementation to find the
// second best MST
  
#include <bits/stdc++.h>
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;
}
Producción

MST: 110
Second Best MST: 121

Complejidad del tiempo – O(VE) donde V – número de vértices en el gráfico de entrada, E – número de aristas en el gráfico de entrada.

Publicación traducida automáticamente

Artículo escrito por eshwitha_reddy y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *