Kalıp #36
Minimum Spanning Tree
İleriKruskal / Prim: tüm düğümleri minimum toplam kenar maliyetiyle bağla.
Ne zaman kullanılır
Graftaki tüm düğümleri minimum toplam kenar ağırlığıyla bağlaman gerekiyorsa. Seyrek graf için Kruskal (kenar sırala + union-find); yoğun için Prim (öncelik kuyruğu).
Tanıma ipuçları
- Tüm düğümleri minimum maliyetle bağla
- MST / minimum spanning tree
- Kümele / şehirleri en ucuza bağla
- Kruskal (kenar sırala) veya Prim (düğümden greedy)
Yaygın tuzaklar
- Kruskal döngü tespiti için union-find gerektirir
- Prim: stale öncelik kuyruğu girişleri
- MST ile en kısa yolu karıştırmak (MST toplamı minimize eder, yol başına değil)
90 saniyelik tanıma egzersizi
Hangisi en iyi uyuyor?
- Tüm düğümleri minimum maliyetle bağla
- MST / minimum spanning tree
- Kümele / şehirleri en ucuza bağla
Etkileşimli
Zihinsel model
Değişmezin tam adım adım anlatımı. Duraklat, noktalara tıkla veya ← → kullan. Her adımı kendi cümlelerinle anlatmayı hedefle.
Kruskal: kenarları sırala, döngüleri atla
Tüm düğümleri minimum toplam ağırlıkla bağla. Kenarlar: AB1, BC2, AC3, BD4, CD5. MST ≠ en kısa yol.
Nasıl düşünülür
MST, ağırlıklı yönsüz graftaki tüm düğümleri minimum toplam kenar ağırlığıyla bağlar. Bir ağaçtır (döngüsüz) ve tüm düğümleri kapsar. Temel içgörü: kenarları ağırlığa göre sırala, döngü oluşturmayacak her kenarı ekle → MST. Bu Kruskal’dır. Ölçekte döngü tespiti union-find demektir: iki uç aynı bileşendeyse kenar ekleme döngü yapar, atla.
Prim MST’yi tek bir tohumdan büyütür: kesiyi geçen kenarların (bir uç ağaçta, diğeri dışarıda) min-heap’ini tut. En ucuzu pop et, dış düğümü ekle, kenarlarını push et. Prim yoğun grafarda (E ~ V²) parlar; tüm E kenarı sıralamak israf. Seyrek graflarda (E ~ V), Kruskal’ın sıralama + union-find’i daha basit ve eşit hızlı.
Şablon şekilleri
| Şekil | Temel hamle | Örnek |
|---|---|---|
| Kruskal | Kenar sırala; union-find döngü atla | LC 1135, LC 1584 |
| Prim | Kesiyi geçen kenar min-heap; tohumdan büyü | LC 1168 |
| Kısıtlı MST | Cevapta ikili arama / kenar filtrele | LC 1489 |
| Offline MST sorguları | Sorgu + kenar sırala; union-find cevap | LC 1724 |
Karmaşıklık temeli
Kruskal: O(E log E) (sıralama) + yaklaşık O(E) union-find. Heap’li Prim: O((V + E) log V). Yoğun graf için heapsiz Prim O(V²).
Şablondan probleme
- Grafın yönsüz ve ağırlıkların karşılaştırılabilir olduğunu doğrula (MST negatifi özel ele almaz).
- Seyrek (E ~ V)? Kruskal. Yoğun (E ~ V²)? Prim.
- Kruskal: kenarları sırala, iterasyon yap, union-find döngü atla, V-1 kenarda dur.
- MST toplam kenar ağırlığını minimize eder, tek tek yolları değil, en kısa yol ile karıştırma.
Şablon
TypeScript, Python ve C#’te aynı iskelet. Değişmezi uyarla; yapıyı koru.
/** MST template: Kruskal with union-find. */
export function kruskalMST(
n: number, edges: [number, number, number][],
): { weight: number; edges: [number, number, number][] } {
const sorted = [...edges].sort((a, b) => a[2]! - b[2]!);
const parent = new Array<number>(n).fill(0).map((_, i) => i);
function find(x: number): number {
if (parent[x] !== x) parent[x] = find(parent[x]!);
return parent[x]!;
}
function union(a: number, b: number): boolean {
const ra = find(a), rb = find(b);
if (ra === rb) return false;
parent[ra] = rb;
return true;
}
let total = 0;
const mst: [number, number, number][] = [];
for (const e of sorted) {
if (mst.length === n - 1) break;
if (union(e[0]!, e[1]!)) {
mst.push(e);
total += e[2]!;
}
}
return { weight: total, edges: mst };
}/** MST template: Kruskal with union-find. */
export function kruskalMST(
n: number, edges: [number, number, number][],
): { weight: number; edges: [number, number, number][] } {
const sorted = [...edges].sort((a, b) => a[2]! - b[2]!);
const parent = new Array<number>(n).fill(0).map((_, i) => i);
function find(x: number): number {
if (parent[x] !== x) parent[x] = find(parent[x]!);
return parent[x]!;
}
function union(a: number, b: number): boolean {
const ra = find(a), rb = find(b);
if (ra === rb) return false;
parent[ra] = rb;
return true;
}
let total = 0;
const mst: [number, number, number][] = [];
for (const e of sorted) {
if (mst.length === n - 1) break;
if (union(e[0]!, e[1]!)) {
mst.push(e);
total += e[2]!;
}
}
return { weight: total, edges: mst };
}- 1#1168 Optimize Water Distribution in VillageRehberhard
- 2#1135 Connecting Cities With Minimum CostRehbermedium
- 3#1489 Find Critical and Pseudo-Critical Edges in MSTRehberhard
- 4#1584 Min Cost to Connect All PointsRehbermedium
- 5#1724 Checking Existence of Edge Length Limited Paths IIRehberhard
- 6#2093 Minimum Cost to Reach City With DiscountsRehberhard