La ruta más corta desde el origen hasta el destino, de modo que los pesos de los bordes a lo largo de la ruta aumentan y disminuyen alternativamente

Dado un grafo conexo con N vértices y M aristas. La tarea es encontrar el camino más corto desde el origen hasta el vértice de destino de manera que la diferencia entre los pesos de los bordes adyacentes en el camino más corto cambie de positivo a negativo y viceversa ( Peso (E1) > Peso (E2) < Peso (E3) … . ). Si no existe tal ruta, imprima -1 .

Ejemplos:

Entrada: fuente = 4, destino = 3

Salida: 19
4 – 2 – 1 – 3 (Pesos de borde: 8, 3, 10) y 4 – 1 – 2 – 3 (Pesos de borde: 6, 3, 10) son los únicos caminos válidos.
El segundo camino toma el costo mínimo, es decir, 19.

Entrada: origen = 2, destino = 4

Salida: -1
No existe tal ruta.

Enfoque: aquí, necesitamos mantener dos copias de listas adyacentes, una para diferencia positiva y otra para diferencia negativa. Tome una cola de prioridad como en el algoritmo de Dijkstras y mantenga cuatro variables a la vez, es decir,

  1. cost: Para almacenar el costo de la ruta hasta el Node actual.
  2. etapa: una variable entera para indicar qué elemento se debe tomar a continuación, si el valor anterior era negativo, entonces se debe tomar un valor positivo; de lo contrario, se debe tomar negativo.
  3. peso: Peso del último Node visitado.
  4. vértice: Último vértice visitado.

Para cada vértice, empuje los vértices adyacentes según la condición requerida (valor de la etapa). Ver el código para una mejor comprensión.

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

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define N 100005
  
// To store the graph
vector<pair<int, int> > incr[N], decr[N];
int _incr[N], _decr[N], shortest[N];
  
int n, m, src, dest, MAXI = 1LL << 30;
  
// Function to add edges
void Add_edge(int x, int y, int w)
{
    incr[x].push_back({ w, y });
    incr[y].push_back({ w, x });
    decr[x].push_back({ -w, y });
    decr[y].push_back({ -w, x });
}
  
// Function to find the shortest distance from
// source to destination
int Modified_Dijkstra()
{
  
    // Total cost, stage, weight of previous, vertex
    priority_queue<pair<pair<int, int>, pair<int, int> > > q;
  
    // Sort the edges
    for (int i = 1; i <= n; i++) {
        sort(incr[i].begin(), incr[i].end());
        sort(decr[i].begin(), decr[i].end());
    }
  
    for (int i = 1; i <= n; i++)
        shortest[i] = MAXI;
  
    // Push the source vertex
    q.push({ { 0, 0 }, { 0, src } });
  
    while (!q.empty()) {
  
        // Take the top element in the queue
        pair<pair<int, int>, pair<int, int> > FRONT = q.top();
  
        // Remove it from the queue
        q.pop();
  
        // Store all the values
        int cost = -FRONT.first.first;
        int stage = FRONT.first.second;
        int weight = FRONT.second.first;
        int v = FRONT.second.second;
  
        // Take the minimum cost for the vertex
        shortest[v] = min(shortest[v], cost);
  
        // If destination vertex has already been visited
        if (shortest[dest] != MAXI)
            break;
  
        // To make difference negative
        if (stage) {
  
            // Start from last not visited vertex
            for (int i = _incr[v]; i < incr[v].size(); i++) {
  
                // If we can take the ith vertex
                if (weight > incr[v][i].first)
                    q.push({ { -(cost + incr[v][i].first), 0 },
                             { incr[v][i].first, incr[v][i].second } });
                else {
  
                    // To keep the last not visited vertex
                    _incr[v] = i;
                    break;
                }
            }
        }
  
        // To make difference positive
        else {
  
            // Start from last not visited vertex
            for (int i = _decr[v]; i < decr[v].size(); i++) {
  
                // If we can take the ith vertex
                if (weight < -decr[v][i].first)
                    q.push({ { -(cost - decr[v][i].first), 1 },
                             { -decr[v][i].first, decr[v][i].second } });
                else {
  
                    // To keep the last not visited vertex
                    _decr[v] = i;
                    break;
                }
            }
        }
    }
  
    if (shortest[dest] == MAXI)
        return -1;
  
    return shortest[dest];
}
  
// Driver code
int main()
{
    n = 5, src = 4, dest = 3;
  
    // Adding edges
    Add_edge(4, 2, 8);
    Add_edge(1, 4, 6);
    Add_edge(2, 3, 10);
    Add_edge(3, 1, 10);
    Add_edge(1, 2, 3);
    Add_edge(3, 5, 3);
  
    cout << Modified_Dijkstra();
  
    return 0;
}
Producción:

19

Publicación traducida automáticamente

Artículo escrito por pawan_asipu 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 *