İçeriğe atla
ΣDSA Patterns
Menü
Dil

En Kısa Yol (Ağırlıklı)

Rehber 4 / 6 · Yol 4 / 6

Etkileşimli

Zihinsel model

Bu problem için animasyonlu çözüm. Adımları kaydır veya boşlukla duraklat; değişmezi yüksek sesle yeniden anlat.

Adım 1 / 6
0d0 w11∞2∞3∞

ways[0] = 1

Ways to arrive: n=4 elmas. Yollar 0-1, 1-3, 0-2, 2-3 hepsi time 1. 0 → 3 en kısa süreli yolları say, mod 10^9+7.

Demo önizleme: Bu çözümler otomatik test paketini geçiyor ama insan tarafından incelenmedi. Trade-off ve yazıları taslak olarak değerlendirin.

Number of Ways to Arrive at Destination

Problem (yeniden ifade)

n kavşak (0 … n-1) ve çift yönlü yollar [u, v, time]. 0’dan n-1’e en kısa süreli kaç yol olduğunu 10^9+7 modunda döndür.

Sezgi

En kısa süreler için Dijkstra çalıştır, yanına ways[] koy. v’ye kesin daha iyi süre bulununca ways[u]’yu kopyala. Aynı süreli başka yol bulununca ways[u] ekle.

Yaklaşımlar

Dijkstra + yol sayıları

Doğrulanmadı
Zaman O((n+E) log n)Alan O(n+E)

Fikir. dist[0] = 0, ways[0] = 1. nd = d + w gevşet: nd < dist[v] ise dist’i yaz, ways[v] = ways[u] ve it; nd == dist[v] ise ways[v] += ways[u] (mod). Eşit durumda tekrar itme — v ilk keşiften heap’te.

Yürüyüş. Sink’e süre 7 olan iki en kısa rota, ortak önek iki kez çatallanırsa resmi örnekteki 4 yol.

Trade-off. LC 743 Dijkstra’sı artı eşit-gevşetme dalı. 64-bit süre (n · 10^9). Çift saymamak için bayat pop’ları atla.

Çözüm
/**
 * Toy PQ: sort + shift. Interview/production: binary heap.
 */
export function countPaths(n: number, roads: number[][]): number {
  const MOD = 1_000_000_007;
  const adj: [number, number][][] = Array.from({ length: n }, () => []);
  for (const [u, v, t] of roads) {
    adj[u]!.push([v, t]);
    adj[v]!.push([u, t]);
  }
  const dist = new Array<number>(n).fill(Infinity);
  const ways = new Array<number>(n).fill(0);
  dist[0] = 0;
  ways[0] = 1;
  const pq: [number, number][] = [[0, 0]];
  while (pq.length) {
    pq.sort((a, b) => a[0]! - b[0]!);
    const [d, u] = pq.shift()!;
    if (d > dist[u]!) continue;
    for (const [v, w] of adj[u]!) {
      const nd = d + w;
      if (nd < dist[v]!) {
        dist[v] = nd;
        ways[v] = ways[u]!;
        pq.push([nd, v]);
      } else if (nd === dist[v]) {
        ways[v] = (ways[v]! + ways[u]!) % MOD;
      }
    }
  }
  return ways[n - 1]!;
}
/**
 * Toy PQ: sort + shift. Interview/production: binary heap.
 */
export function countPaths(n: number, roads: number[][]): number {
  const MOD = 1_000_000_007;
  const adj: [number, number][][] = Array.from({ length: n }, () => []);
  for (const [u, v, t] of roads) {
    adj[u]!.push([v, t]);
    adj[v]!.push([u, t]);
  }
  const dist = new Array<number>(n).fill(Infinity);
  const ways = new Array<number>(n).fill(0);
  dist[0] = 0;
  ways[0] = 1;
  const pq: [number, number][] = [[0, 0]];
  while (pq.length) {
    pq.sort((a, b) => a[0]! - b[0]!);
    const [d, u] = pq.shift()!;
    if (d > dist[u]!) continue;
    for (const [v, w] of adj[u]!) {
      const nd = d + w;
      if (nd < dist[v]!) {
        dist[v] = nd;
        ways[v] = ways[u]!;
        pq.push([nd, v]);
      } else if (nd === dist[v]) {
        ways[v] = (ways[v]! + ways[u]!) % MOD;
      }
    }
  }
  return ways[n - 1]!;
}

Şablon bağlantısı

Dijkstra, kesin iyileştirmede kopyalanan / berabere eklenen ekstra ways[] ile. Heap hâlâ yalnızca mesafeye göre.

Yansıma