Apuntes DAM
Volver al inicio

Algoritmo de Dijkstra

AlgoritmosGrafosNivel avanzadoTambién: Dijkstra, camino más corto, caminos mínimos, shortest path

El camino más corto desde un nodo a todos los demás en un grafo con pesos no negativos: fija cada vez el nodo pendiente más cercano con una cola de prioridad. Es lo que hay detrás de un GPS.

Visualízalo paso a paso

Cambia los datos, dale a reproducir y sigue cada paso en el dibujo, en la línea de Java que se ejecuta y en sus variables.

Dijkstra

Escribe las aristas con su peso y el nodo de salida: Dijkstra encuentra la distancia más corta a todos los demás, fijando cada vez el más cercano.

Como «A-B:4, A-C:2»: pesos de 0 a 99, sin negativos
  • distancia provisional

Paso 1

Todas las distancias empiezan en ∞ menos la de A, que es 0. En la cola de prioridad entra (0, A).

1static Map<String, Integer> dijkstra(Map<String, Map<String, Integer>> g, String origen) {
2    Map<String, Integer> dist = new HashMap<>();
3    for (String v : g.keySet()) dist.put(v, Integer.MAX_VALUE);
4    dist.put(origen, 0);  // dist = A=0 B=∞ C=∞ D=∞ E=∞ F=∞
5    PriorityQueue<Map.Entry<String, Integer>> cola = new PriorityQueue<>(Map.Entry.comparingByValue());
6    cola.add(Map.entry(origen, 0));
7    Set<String> fijos = new HashSet<>();
8    while (!cola.isEmpty()) {
9        String u = cola.poll().getKey();
10        if (!fijos.add(u)) continue;
11        for (var e : g.get(u).entrySet()) {
12            int nueva = dist.get(u) + e.getValue();
13            if (nueva < dist.get(e.getKey())) {
14                dist.put(e.getKey(), nueva);
15                cola.add(Map.entry(e.getKey(), nueva));
16            }
17        }
18    }
19    return dist;
20}

Variables

dist
A=0 B=∞ C=∞ D=∞ E=∞ F=∞

Atajos con el foco dentro del visualizador: ← → paso a paso, Espacio reproducir o pausar, Inicio/Fin ir al principio o al final.

La idea

Cuando las aristas tienen pesos (kilómetros, minutos, euros), el camino con menos aristas ya no es el más corto: dos tramos de 100 km son mejores que uno de 300. El algoritmo de Dijkstra (1956) calcula las distancias mínimas desde un origen a todos los nodos, siempre que ningún peso sea negativo.

Mantiene una distancia provisional para cada nodo (∞ al principio, 0 el origen) y repite: coge el nodo pendiente con menor distancia provisional y lo fija, porque ya no puede mejorar. Después «relaja» sus aristas: para cada vecino, si llegar a través del nodo fijado es más corto que lo que se tenía, actualiza su distancia y apunta de dónde viene.

¿Por qué es seguro fijar el más cercano? Porque cualquier otro camino hasta él tendría que pasar por algún nodo pendiente, que ya está igual o más lejos, y después sumar pesos que no son negativos: no puede salir más corto. Por eso mismo falla con pesos negativos: una arista negativa encontrada tarde podría abaratar un nodo ya fijado.

Para coger rápido el más cercano se usa una cola de prioridad (un montículo). La versión habitual no actualiza las entradas que ya están en la cola: mete una nueva cada vez que una distancia mejora y, al sacar una entrada de un nodo ya fijado, la ignora. Es más sencilla y cuesta O((V + E) log V).

Cuándo usarlo

  • Rutas en mapas: el GPS y los planificadores de viaje, con pesos en km o en minutos.
  • Encaminamiento en redes: el protocolo OSPF calcula con Dijkstra las rutas de cada router.
  • Cualquier problema de «coste mínimo» que se pueda ver como un grafo: el terreno más fácil en un mapa, la cadena de conversiones más barata.
  • Juegos: el movimiento por terreno con costes distintos (A* es Dijkstra con una estimación de lo que falta).

Cuándo no

  • Con pesos negativos: el resultado puede ser falso sin ningún aviso; usa Bellman-Ford.
  • Si todas las aristas pesan lo mismo: BFS hace lo mismo más rápido y con menos código.
  • Si necesitas las distancias entre todos los pares en un grafo pequeño y denso: Floyd-Warshall es más directo.
  • Si solo te interesa un destino y tienes una buena estimación de lo que falta (la distancia en línea recta): A* explora mucho menos.

Paso a paso

  1. Inicializar. Distancia 0 al origen e ∞ al resto; mete (0, origen) en la cola de prioridad.
  2. Sacar el más cercano. Saca la entrada de menor distancia. Si su nodo ya estaba fijado, es una entrada vieja: ignórala. Si no, fíjalo.
  3. Relajar sus aristas. Para cada vecino, suma la distancia del nodo fijado y el peso de la arista. Si mejora la que tenía, actualízala, apunta el anterior y mete la nueva entrada en la cola.
  4. Reconstruir. Cuando la cola se vacía, las distancias son definitivas. Para el camino, sigue los anteriores desde el destino hasta el origen.

El código

Rutas entre ciudades

Distancias aproximadas por carretera. Se imprime el orden en que se fijan las ciudades (de más cerca a más lejos) y dos rutas reconstruidas con los anteriores.

Java
1import java.util.*;
2
3public class Main {
4    static final Map<String, Map<String, Integer>> mapa = new LinkedHashMap<>();
5
6    static void carretera(String a, String b, int km) {
7        mapa.computeIfAbsent(a, k -> new LinkedHashMap<>()).put(b, km);
8        mapa.computeIfAbsent(b, k -> new LinkedHashMap<>()).put(a, km);
9    }
10
11    record Entrada(String ciudad, int km) { }
12
13    public static void main(String[] args) {
14        carretera("Madrid", "Zaragoza", 315);              // km aproximados
15        carretera("Zaragoza", "Barcelona", 300);
16        carretera("Madrid", "Valencia", 355);
17        carretera("Valencia", "Barcelona", 350);
18        carretera("Madrid", "Bilbao", 400);
19        carretera("Bilbao", "Zaragoza", 305);
20        carretera("Madrid", "Granada", 420);
21        carretera("Granada", "Málaga", 125);
22        carretera("Madrid", "Sevilla", 530);
23        carretera("Sevilla", "Málaga", 205);
24        carretera("Sevilla", "Granada", 250);
25        carretera("Valencia", "Murcia", 240);
26        carretera("Murcia", "Granada", 280);
27
28        Map<String, Integer> dist = new HashMap<>();
29        Map<String, String> previa = new HashMap<>();
30        Set<String> fijas = new LinkedHashSet<>();             // en el orden en que se fijan
31        PriorityQueue<Entrada> cola = new PriorityQueue<>(Comparator.comparingInt(Entrada::km));
32        dist.put("Madrid", 0);
33        cola.add(new Entrada("Madrid", 0));
34        while (!cola.isEmpty()) {
35            Entrada e = cola.poll();                           // la más cercana de las pendientes
36            if (!fijas.add(e.ciudad())) continue;              // entrada vieja: ya estaba fijada
37            for (Map.Entry<String, Integer> c : mapa.get(e.ciudad()).entrySet()) {
38                int nueva = e.km() + c.getValue();
39                if (nueva < dist.getOrDefault(c.getKey(), Integer.MAX_VALUE)) {
40                    dist.put(c.getKey(), nueva);
41                    previa.put(c.getKey(), e.ciudad());
42                    cola.add(new Entrada(c.getKey(), nueva));
43                }
44            }
45        }
46        System.out.println("Orden en que se fijan las ciudades:");
47        for (String c : fijas) System.out.println("  " + c + ": " + dist.get(c) + " km");
48        for (String destino : List.of("Barcelona", "Málaga")) {
49            LinkedList<String> camino = new LinkedList<>();
50            for (String c = destino; c != null; c = previa.get(c)) camino.addFirst(c);
51            System.out.println("Madrid → " + destino + ": " + String.join(" → ", camino));
52        }
53    }
54}

Salida al ejecutarlo (la misma en los 5 lenguajes)

Orden en que se fijan las ciudades:
  Madrid: 0 km
  Zaragoza: 315 km
  Valencia: 355 km
  Bilbao: 400 km
  Granada: 420 km
  Sevilla: 530 km
  Málaga: 545 km
  Murcia: 595 km
  Barcelona: 615 km
Madrid → Barcelona: Madrid → Zaragoza → Barcelona
Madrid → Málaga: Madrid → Granada → Málaga

Con pesos negativos, Dijkstra se equivoca

Un grafo dirigido de cuatro nodos con una arista negativa. Bellman-Ford, que repite la relajación de todas las aristas V − 1 veces, da la respuesta correcta.

Java
1import java.util.*;
2
3public class Main {
4    record Arista(String de, String a, int peso) { }
5    record Entrada(String nodo, int d) { }
6
7    static final List<String> NODOS = List.of("A", "B", "C", "D");
8    static final List<Arista> ARISTAS = List.of(new Arista("A", "B", 2), new Arista("A", "C", 5),
9            new Arista("C", "B", -4), new Arista("B", "D", 1));
10
11    static Map<String, Integer> dijkstra(String origen) {
12        Map<String, Integer> dist = new LinkedHashMap<>();
13        for (String n : NODOS) dist.put(n, Integer.MAX_VALUE);
14        dist.put(origen, 0);
15        Set<String> fijos = new HashSet<>();
16        PriorityQueue<Entrada> cola = new PriorityQueue<>(Comparator.comparingInt(Entrada::d));
17        cola.add(new Entrada(origen, 0));
18        while (!cola.isEmpty()) {
19            Entrada e = cola.poll();
20            if (!fijos.add(e.nodo())) continue;
21            for (Arista a : ARISTAS)
22                if (a.de().equals(e.nodo()) && e.d() + a.peso() < dist.get(a.a())) {
23                    dist.put(a.a(), e.d() + a.peso());
24                    cola.add(new Entrada(a.a(), e.d() + a.peso()));
25                }
26        }
27        return dist;
28    }
29
30    /** Bellman-Ford: relaja TODAS las aristas V − 1 veces. Más lento, pero admite pesos negativos. */
31    static Map<String, Integer> bellmanFord(String origen) {
32        Map<String, Integer> dist = new LinkedHashMap<>();
33        for (String n : NODOS) dist.put(n, Integer.MAX_VALUE);
34        dist.put(origen, 0);
35        for (int i = 1; i < NODOS.size(); i++)
36            for (Arista a : ARISTAS)
37                if (dist.get(a.de()) != Integer.MAX_VALUE && dist.get(a.de()) + a.peso() < dist.get(a.a()))
38                    dist.put(a.a(), dist.get(a.de()) + a.peso());
39        return dist;
40    }
41
42    static String texto(Map<String, Integer> dist) {
43        StringJoiner sj = new StringJoiner(" ");
44        dist.forEach((n, d) -> sj.add(n + "=" + d));
45        return sj.toString();
46    }
47
48    public static void main(String[] args) {
49        System.out.println("Dijkstra:     " + texto(dijkstra("A")));
50        System.out.println("Bellman-Ford: " + texto(bellmanFord("A")));
51        System.out.println("D sale mal con Dijkstra: B se fijó con 2 y, cuando C → B lo bajó a 1, ya no se propagó a D.");
52    }
53}

Salida al ejecutarlo (la misma en los 5 lenguajes)

Dijkstra:     A=0 B=1 C=5 D=3
Bellman-Ford: A=0 B=1 C=5 D=2
D sale mal con Dijkstra: B se fijó con 2 y, cuando C → B lo bajó a 1, ya no se propagó a D.

Traza: Dijkstra desde A en el grafo del visualizador

Sale de la colaQué pasaMejorasDistancias
A:0se fija AB → 4, C → 2A=0 B=4 C=2 D=∞ E=∞ F=∞
C:2se fija CB → 3, D → 10, E → 12A=0 B=3 C=2 D=10 E=12 F=∞
B:3se fija BD → 8A=0 B=3 C=2 D=8 E=12 F=∞
B:4entrada vieja: se ignora—A=0 B=3 C=2 D=8 E=12 F=∞
D:8se fija DE → 10, F → 14A=0 B=3 C=2 D=8 E=10 F=14
D:10entrada vieja: se ignora—A=0 B=3 C=2 D=8 E=10 F=14
E:10se fija EF → 12A=0 B=3 C=2 D=8 E=10 F=12
E:12entrada vieja: se ignora—A=0 B=3 C=2 D=8 E=10 F=12
F:12se fija F—A=0 B=3 C=2 D=8 E=10 F=12
F:14entrada vieja: se ignora—A=0 B=3 C=2 D=8 E=10 F=12

Las entradas viejas (B:4, D:10, E:12, F:14) se quedan en la cola y se descartan al salir: es más barato que buscarlas para actualizarlas.

Complejidad

VersiónTiempoCuándo conviene
Dijkstra con montículo binarioO((V + E) log V)Grafos dispersos: lo normal (mapas, redes)
Dijkstra con array (buscar el mínimo a mano)O(V²)Grafos muy densos (E cerca de V²)
BFS (todas las aristas pesan 1)O(V + E)Sin pesos
Bellman-FordO(V · E)Hay pesos negativos (y detecta los ciclos negativos)
Floyd-WarshallO(V³)Todas las parejas en un grafo pequeño

Cada mejora mete una entrada en la cola (como mucho E) y cada salida cuesta log: de ahí el (V + E) log V.

0102030405015101520tamaño de la entrada (n)operacionesO(n!)O(2ⁿ)O(n²)O(n log n)O(1)O(log n)O(n)
  • Mejor caso: O(n log n)
  • Caso medio: O(n log n)
  • Peor caso: O(n log n)

O((V + E) log V) con un montículo: cada mejora mete una entrada en la cola y cada salida cuesta log. Sin montículo (buscando el mínimo a mano) es O(V²). Las curvas grises son las demás clases, para comparar.

En la práctica

  • Google Maps y los GPS usan variantes de Dijkstra y A* con mucho preprocesado del mapa (jerarquías de carreteras) para responder en milisegundos.
  • OSPF e IS-IS, los protocolos de encaminamiento de las redes grandes, calculan con Dijkstra el árbol de caminos más cortos de cada router.
  • Los videojuegos calculan rutas por terrenos con costes distintos (A* es Dijkstra con una heurística).
  • Las aplicaciones de transporte público combinan tiempos de trayecto y de transbordo como pesos.
  • Java no trae un Dijkstra en la biblioteca estándar, pero sí la pieza clave: PriorityQueue.

Errores típicos

  • Usarlo con pesos negativos: da distancias falsas sin avisar.
  • No descartar las entradas viejas al sacarlas: se vuelve a procesar un nodo con una distancia peor.
  • Fijar un nodo al meterlo en la cola en vez de al sacarlo.
  • Inicializar con Integer.MAX_VALUE y sumarle un peso: desborda y se vuelve negativo. Comprueba antes que la distancia no es «infinita».
  • Comparar en la cola por el nombre del nodo, o meter el nodo sin su distancia: la cola de prioridad tiene que ordenar por distancia.

Ejercicios

Cada ejercicio se corrige solo con sus pruebas (algunas ocultas). Escribe tu solución en el editor y pulsa Ejecutar o Comprobar; la solución explicada está debajo, por si te atascas.

1. La ruta más corta entre ciudades

Cada línea con dos ciudades y un número es una carretera de doble sentido con sus kilómetros. Las líneas que empiezan por ? preguntan la ruta más corta entre dos ciudades. El main ya guarda las carreteras y reconstruye la ruta con previa: completa dijkstra.

  • Carretera: Madrid Zaragoza 315 (si una carretera aparece dos veces, vale la más corta). Consulta: ? Madrid Barcelona.
  • Respuesta: Madrid → Barcelona: 615 km (Madrid, Zaragoza, Barcelona); de una ciudad a sí misma, 0 km (Madrid).
  • Si no hay ruta: Madrid → Palma: sin ruta. Ciudad que no está en ninguna carretera: No conozco Lisboa. Otra cosa: Línea no válida: «…».
  • En las pruebas, la ruta más corta siempre es única.
☕JavaLa ruta más corta entre ciudadesMedio

Ejemplo

Entrada (lo que se escribe por teclado)
Madrid Zaragoza 315
Zaragoza Barcelona 300
Madrid Valencia 355
Valencia Barcelona 350
Madrid Bilbao 400
Bilbao Zaragoza 305
Madrid Granada 420
Granada Malaga 125
Madrid Sevilla 530
Sevilla Malaga 205
Sevilla Granada 250
Valencia Murcia 240
Murcia Granada 280
? Madrid Barcelona
? Madrid Malaga
? Barcelona Sevilla
Salida esperada
Madrid → Barcelona: 615 km (Madrid, Zaragoza, Barcelona)
Madrid → Malaga: 545 km (Madrid, Granada, Malaga)
Barcelona → Sevilla: 1120 km (Barcelona, Valencia, Murcia, Granada, Sevilla)
⏳
Test oculto #3
⏳
Test oculto #4
⏳
Test oculto #5
0/5 tests pasados · pulsa un test para ver su entrada y su salida esperada
Ver la solución explicada
java
1import java.util.*;
2
3public class Main {
4    static final Map<String, Map<String, Integer>> carreteras = new TreeMap<>();
5    static final Map<String, Integer> dist = new HashMap<>();      // km desde el origen
6    static final Map<String, String> previa = new HashMap<>();     // desde qué ciudad se llega a cada una
7
8    record Entrada(String ciudad, int km) { }
9
10    /** Dijkstra desde origen: rellena dist (solo con las ciudades alcanzables) y previa. */
11    static void dijkstra(String origen) {
12        PriorityQueue<Entrada> cola = new PriorityQueue<>(Comparator.comparingInt(Entrada::km));
13        Set<String> fijas = new HashSet<>();
14        dist.put(origen, 0);
15        cola.add(new Entrada(origen, 0));
16        while (!cola.isEmpty()) {
17            Entrada e = cola.poll();
18            if (!fijas.add(e.ciudad())) continue;              // entrada vieja
19            for (Map.Entry<String, Integer> c : carreteras.get(e.ciudad()).entrySet()) {
20                int nueva = e.km() + c.getValue();
21                if (nueva < dist.getOrDefault(c.getKey(), Integer.MAX_VALUE)) {
22                    dist.put(c.getKey(), nueva);
23                    previa.put(c.getKey(), e.ciudad());
24                    cola.add(new Entrada(c.getKey(), nueva));
25                }
26            }
27        }
28    }
29
30    public static void main(String[] args) {
31        Scanner sc = new Scanner(System.in);
32        while (sc.hasNextLine()) {
33            String linea = sc.nextLine().trim();
34            if (linea.isEmpty()) continue;
35            String[] p = linea.split("\\s+");
36            if (p[0].equals("?") && p.length == 3) {
37                String a = p[1], b = p[2];
38                if (!carreteras.containsKey(a) || !carreteras.containsKey(b)) {
39                    System.out.println("No conozco " + (carreteras.containsKey(a) ? b : a));
40                    continue;
41                }
42                dist.clear();
43                previa.clear();
44                dijkstra(a);
45                if (!dist.containsKey(b)) {
46                    System.out.println(a + " → " + b + ": sin ruta");
47                    continue;
48                }
49                LinkedList<String> ruta = new LinkedList<>();
50                for (String c = b; !c.equals(a); c = previa.get(c)) ruta.addFirst(c);
51                ruta.addFirst(a);
52                System.out.println(a + " → " + b + ": " + dist.get(b) + " km (" + String.join(", ", ruta) + ")");
53            } else if (p.length == 3 && !p[0].equals("?") && !p[0].equals(p[1]) && p[2].matches("\\d{1,5}")) {
54                int km = Integer.parseInt(p[2]);
55                carreteras.computeIfAbsent(p[0], k -> new TreeMap<>()).merge(p[1], km, Math::min);
56                carreteras.computeIfAbsent(p[1], k -> new TreeMap<>()).merge(p[0], km, Math::min);
57            } else System.out.println("Línea no válida: «" + linea + "»");
58        }
59    }
60}

Es el Dijkstra de la ficha sobre un grafo leído de la entrada. previa guarda el último paso de la ruta más corta a cada ciudad; seguirlo hacia atrás desde el destino da la ruta entera.

Ojo con la primera prueba: de Barcelona a Sevilla la ruta más corta no pasa por Madrid, sino por Valencia, Murcia y Granada. Contar tramos (BFS) daría otra.

2. El terreno más fácil

El mapa es una cuadrícula de dígitos del 1 al 9: lo que cuesta entrar en esa casilla. Las casillas # son muros. Calcula el coste mínimo para ir de la esquina de arriba a la izquierda a la de abajo a la derecha moviéndote en horizontal o vertical (la casilla de salida no se paga). La lectura del mapa ya está hecha: completa costeMinimo.

  • Entrada: el mapa, una fila por línea, todas del mismo ancho.
  • Salida: Coste mínimo: 40, o Sin camino si no se puede llegar (o si la salida o la llegada son muros).
  • Si una fila tiene otro ancho u otros caracteres: Mapa no válido en la fila 3: «…».
☕JavaEl terreno más fácilDifícil

Ejemplo

Entrada (lo que se escribe por teclado)
11637
13813
21365
36949
74634
Salida esperada
Coste mínimo: 24
⏳
Test oculto #3
⏳
Test oculto #4
⏳
Test oculto #5
⏳
Test oculto #6
⏳
Test oculto #7
0/7 tests pasados · pulsa un test para ver su entrada y su salida esperada
Ver la solución explicada
java
1import java.util.*;
2
3public class Main {
4    static char[][] mapa;          // '1'..'9': lo que cuesta entrar en la casilla; '#': muro
5    static int filas, cols;
6
7    /** El coste mínimo para ir de la esquina de arriba a la izquierda a la de abajo a la derecha, sumando
8        lo que cuesta entrar en cada casilla (la de salida no cuenta); -1 si no se puede. */
9    static int costeMinimo() {
10        if (mapa[0][0] == '#' || mapa[filas - 1][cols - 1] == '#') return -1;
11        int[][] dist = new int[filas][cols];
12        for (int[] fila : dist) Arrays.fill(fila, Integer.MAX_VALUE);
13        PriorityQueue<int[]> cola = new PriorityQueue<>(Comparator.comparingInt(e -> e[0]));   // {coste, fila, columna}
14        int[] df = {-1, 1, 0, 0}, dc = {0, 0, -1, 1};
15        dist[0][0] = 0;
16        cola.add(new int[]{0, 0, 0});
17        while (!cola.isEmpty()) {
18            int[] e = cola.poll();
19            int d = e[0], f = e[1], c = e[2];
20            if (d > dist[f][c]) continue;                      // entrada vieja
21            if (f == filas - 1 && c == cols - 1) return d;    // el destino ya está fijado
22            for (int k = 0; k < 4; k++) {
23                int nf = f + df[k], nc = c + dc[k];
24                if (nf < 0 || nf >= filas || nc < 0 || nc >= cols || mapa[nf][nc] == '#') continue;
25                int nueva = d + (mapa[nf][nc] - '0');
26                if (nueva < dist[nf][nc]) {
27                    dist[nf][nc] = nueva;
28                    cola.add(new int[]{nueva, nf, nc});
29                }
30            }
31        }
32        return -1;
33    }
34
35    public static void main(String[] args) {
36        Scanner sc = new Scanner(System.in);
37        List<String> lineas = new ArrayList<>();
38        while (sc.hasNextLine()) {
39            String l = sc.nextLine().trim();
40            if (!l.isEmpty()) lineas.add(l);
41        }
42        if (lineas.isEmpty()) {
43            System.out.println("Mapa vacío");
44            return;
45        }
46        filas = lineas.size();
47        cols = lineas.get(0).length();
48        mapa = new char[filas][];
49        for (int f = 0; f < filas; f++) {
50            String l = lineas.get(f);
51            if (l.length() != cols || !l.matches("[1-9#]+")) {
52                System.out.println("Mapa no válido en la fila " + (f + 1) + ": «" + l + "»");
53                return;
54            }
55            mapa[f] = l.toCharArray();
56        }
57        int coste = costeMinimo();
58        System.out.println(coste < 0 ? "Sin camino" : "Coste mínimo: " + coste);
59    }
60}

Con BFS no basta, porque no todos los pasos cuestan lo mismo; y probar todos los caminos (DFS con vuelta atrás) es exponencial. Dijkstra visita cada casilla una vez, con un coste O(n log n) en el número de casillas.

Comprobar d > dist[f][c] al sacar sustituye al conjunto de fijados: si la entrada no coincide con la mejor distancia conocida, es vieja.

Test

Test: Algoritmo de Dijkstra

0/5 respondidas · 0 aciertos

Elige una respuesta en cada pregunta: verás al momento si es correcta y por qué. Con un 80 % de aciertos se da por superada.

  1. 1.¿Qué condición tienen que cumplir los pesos para que Dijkstra sea correcto?

  2. 2.¿Qué nodo se fija en cada paso?

  3. 3.¿Qué significa «relajar» la arista u → v?

  4. 4.¿Qué coste tiene Dijkstra con un montículo binario?

  5. 5.Al sacar de la cola una entrada de un nodo que ya estaba fijado…

Relacionado