Inicio > Cursos > Algoritmos > Dijkstra y Caminos Mínimos
AlgoritmosTécnicas AvanzadasLección 16 de 19

Dijkstra y Caminos Mínimos

Dijkstra es el algoritmo de caminos más cortos más famoso. La idea: mantén la distancia mínima conocida desde el origen a cada nodo. Empieza en el origen con distancia 0. En cada paso, toma el nodo no visitado con menor distancia (usando un Min-Heap para hacerlo eficientemente), y actualiza las distancias de sus vecinos. Repite hasta procesar todos los nodos. La restricción: no funciona con pesos negativos (para eso existe Bellman-Ford).

Dijkstra está detrás de muchos sistemas que usas diariamente. El GPS de tu teléfono usa una variación de Dijkstra (con A* para mayor eficiencia) para calcular la ruta más rápida. Los routers de internet usan OSPF, un protocolo basado en Dijkstra, para determinar por dónde enviar los paquetes.

Los juegos de estrategia usan pathfinding con A* (Dijkstra con una heurística) para mover personajes por el mapa. Entender Dijkstra es entender la infraestructura digital moderna.

// Dijkstra con Min-Heap (simplificado con array)
function dijkstra(grafo, inicio) {
  // grafo = { A: [[B, 4], [C, 2]], B: [[D, 3]], ... }
  const distancias = {};
  const visitados = new Set();
  
  // Inicializar distancias a Infinity
  for (const nodo in grafo) distancias[nodo] = Infinity;
  distancias[inicio] = 0;
  
  // Priority queue simulada (en prod usar un heap real)
  const cola = [[0, inicio]]; // [distancia, nodo]
  
  while (cola.length > 0) {
    // Extraer el nodo con menor distancia
    cola.sort((a, b) => a[0] - b[0]);
    const [dist, nodo] = cola.shift();
    
    if (visitados.has(nodo)) continue;
    visitados.add(nodo);
    
    for (const [vecino, peso] of (grafo[nodo] || [])) {
      const nuevaDist = dist + peso;
      if (nuevaDist < distancias[vecino]) {
        distancias[vecino] = nuevaDist;
        cola.push([nuevaDist, vecino]);
      }
    }
  }
  
  return distancias;
}

// Ejemplo: red de ciudades
const red = {
  "Madrid":   [["Barcelona", 621], ["Sevilla", 540], ["Valencia", 357]],
  "Barcelona":[["Madrid", 621], ["Valencia", 349]],
  "Sevilla":  [["Madrid", 540], ["Valencia", 650]],
  "Valencia": [["Madrid", 357], ["Barcelona", 349], ["Sevilla", 650]]
};

console.log(dijkstra(red, "Sevilla"));
// { Sevilla: 0, Madrid: 540, Valencia: 650, Barcelona: 889 }
// Nota: Sevilla→Valencia→Barcelona (650+349=999) vs calculado: 889
// En realidad: Sevilla→Madrid(540)→Barcelona(621+540=... no)
// Sevilla→Madrid(540)→Valencia(540+357=897)...Barcelona=897+349=1246
// O Sevilla→Valencia(650)→Barcelona(650+349=999)

// Bellman-Ford: cuando hay pesos negativos
// Floyd-Warshall: caminos más cortos entre TODOS los pares
// Algoritmo de Prim / Kruskal: árbol de expansión mínima
Consejo⚠️ Dijkstra NO funciona con pesos negativos. Para pesos negativos usa Bellman-Ford (O(VE)). Para todos los pares de nodos usa Floyd-Warshall (O(V³)).
← Union-Find (Disjoint Set)DP: Coin Change y LCS →

Practica esta lección

Resuelve los ejercicios del curso de Algoritmos en la app, gratis y con corrección automática.

Empezar a practicar