10. Graflar: BFS va DFS
Nazariya
Graf nima
Graf — tugunlar (vertex) va ularni bog‘lovchi qirralar (edge).
Shahar va yo‘llar, do‘stlar tarmog‘i, labirint kataklari — bularning
hammasi graf.
Tasvirlash
Qo‘shnilar ro‘yxati — eng ko‘p ishlatiladigan usul:
graf = [[] for _ in range(n + 1)]
for _ in range(m):
u, v = map(int, input().split())
graf[u].append(v)
graf[v].append(u) # yo‘naltirilmagan graf uchunDFS — chuqurlikka
Bir yo‘nalishda oxirigacha borib, keyin qaytadi:
korilgan = [False] * (n + 1)
def dfs(u):
korilgan[u] = True
for v in graf[u]:
if not korilgan[v]:
dfs(v)Nima uchun: bog‘langan qismlarni sanash, sikl topish, daraxtni
aylanish.
BFS — kenglikka
Qavat-qavat tarqaladi va eng qisqa yo‘lni (qirralar soni bo‘yicha)
topadi:
from collections import deque
masofa = [-1] * (n + 1)
masofa[boshlanish] = 0
navbat = deque([boshlanish])
while navbat:
u = navbat.popleft()
for v in graf[u]:
if masofa[v] == -1:
masofa[v] = masofa[u] + 1
navbat.append(v)deque shart: oddiy ro‘yxatda pop(0) O(n) vaqt oladi va butun
algoritm sekinlashadi.
Qaysi biri qachon
| Savol | Usul |
|---|---|
| Yo‘l bormi | DFS yoki BFS |
| Eng qisqa yo‘l (qirralar bo‘yicha) | BFS |
| Bog‘langan qismlar soni | DFS yoki BFS |
| Sikl bormi | DFS |
| Og‘irlikli grafda eng qisqa yo‘l | Dijkstra |
Murakkablik
Ikkalasi ham O(n + m): har bir tugun bir marta ko‘riladi, har bir
qirra bir marta tekshiriladi.
Rekursiv DFS xavfi
Zanjir shaklidagi grafda chuqurlik n ga yetadi. n = 10⁵ bo‘lsa,
rekursiya cheklovga uriladi — u holda DFS ni ham navbat (stek) bilan,
sikl ko‘rinishida yozish kerak.
Misol
from collections import deque
masofa = [-1] * (n + 1)
masofa[1] = 0
navbat = deque([1])
while navbat:
u = navbat.popleft()
for v in graf[u]:
if masofa[v] == -1:
masofa[v] = masofa[u] + 1
navbat.append(v)
Mashq masalalari
| ✓ | Kod | Masala | Qiyinlik |
|---|---|---|---|
| AL10-1 | Bog‘langan bo‘laklar | Boshlang‘ich | |
| AL10-2 | Eng qisqa yo‘l | Oson | |
| AL10-3 | Labirint | O‘rta | |
| AL10-4 | Orollar | O‘rta | |
| AL10-5 | Ikki jamoa | Qiyin |