diff --git a/09-grafy/abstraktni-matice.py b/09-grafy/abstraktni-matice.py
new file mode 100755
index 0000000000000000000000000000000000000000..1dfa32d0035a03939f2a14f6fb3c82033c11b818
--- /dev/null
+++ b/09-grafy/abstraktni-matice.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python3
+# Abstraktní reprezentace grafu třídou,
+# implementace třídy pomocí matice sousednosti
+
+from collections import deque
+
+class Graf:
+    """Reprezentace grafu maticí sousednosti."""
+
+    def __init__(self, n):
+        self.n = n
+        self.matice = [[0]*n for _ in range(n)]
+
+    def __repr__(self):
+        return str(self.matice)
+
+    def pridej_hranu(self, i, j):
+        self.matice[i][j] = 1
+
+    # Na cyklus přes všechny vrcholy tentokrát potřebujeme vyrobit
+    # iterátor. Pozor, nestačí definovat metodu __iter__, protože
+    # potřebujeme předat jako parametr vrchol, jehož sousedy chceme
+    # vyjmenovat.
+    def sousede(self, i):
+        return SousedeIt(self, i)
+
+class SousedeIt:
+    """Iterátor přes sousedy zadaného vrcholu."""
+
+    def __init__(self, graf, i):
+        # Iterátor si pamatuje:
+        self.graf = graf    # ke kterému grafu patří
+        self.i = i          # sousedy kterého vrcholu vyjmenovává
+        self.j = 0          # aktuální polohu
+
+    # Pozor: Pokud napíšeme "for v in graf.sousede(u)", cyklus for bude chtít
+    # po objektu vráceném z metody sousede, aby vyrobil svůj iterátor. Jenže
+    # v našem případě to už iterátor je, tak ho musíme naučit, aby vrátil sám
+    # sebe. To je v Pythonu standardní postup: když iterátoru řeknete, že má
+    # vyrobit iterátor, vrátí sebe sama.
+    def __iter__(self):
+        return self
+
+    # Vrátí dalšího souseda v pořadí
+    def __next__(self):
+        # Kde je další jednička v řádku?
+        while self.j < self.graf.n and self.graf.matice[self.i][self.j] == 0:
+            self.j += 1
+        if self.j < self.graf.n:
+            self.j += 1
+            return self.j - 1
+        else:
+            raise StopIteration
+
+
+# Původní příklad na prohledávání do šířky jsme přepsali tak,
+# aby s grafem pracoval výhradně pomocí třídy Graf.
+
+n = int(input())
+graf = Graf(n)
+for i in range(n):
+    for j in input().split():
+        graf.pridej_hranu(i, int(j))
+
+print(graf)
+
+def prohledej(v0):
+    byl_jsem = [False] * n
+    byl_jsem[v0] = True
+    vzdalenost = [None] * n
+    vzdalenost[v0] = 0
+    fronta = deque()
+    fronta.append(v0)
+
+    while fronta:
+        u = fronta.popleft()
+        print(u, vzdalenost[u])
+        for v in graf.sousede(u):
+            if not byl_jsem[v]:
+                byl_jsem[v] = True
+                vzdalenost[v] = vzdalenost[u] + 1
+                fronta.append(v)
+
+prohledej(3)
diff --git a/09-grafy/abstraktni-seznamy.py b/09-grafy/abstraktni-seznamy.py
new file mode 100755
index 0000000000000000000000000000000000000000..b0f5ca720aba92944bb25a6267607c4ba746ea9d
--- /dev/null
+++ b/09-grafy/abstraktni-seznamy.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python3
+# Abstraktní reprezentace grafu třídou,
+# implementace třídy pomocí seznamů sousedů.
+
+from collections import deque
+
+class Graf:
+    """Reprezentace grafu seznamy sousedů."""
+
+    def __init__(self, n):
+        self.n = n
+        self.seznam_sousedu = [[] for _ in range(n)]
+
+    def __repr__(self):
+        return str(self.seznam_sousedu)
+
+    def pridej_hranu(self, i, j):
+        self.seznam_sousedu[i].append(j)
+
+    # Používáme jako "for v in graf.sousede(u)"
+    def sousede(self, i):
+        return self.seznam_sousedu[i]
+
+
+# Původní příklad na prohledávání do šířky jsme přepsali tak,
+# aby s grafem pracoval výhradně pomocí třídy Graf.
+
+n = int(input())
+graf = Graf(n)
+for i in range(n):
+    for j in input().split():
+        graf.pridej_hranu(i, int(j))
+
+print(graf)
+
+def prohledej(v0):
+    byl_jsem = [False] * n
+    byl_jsem[v0] = True
+    vzdalenost = [None] * n
+    vzdalenost[v0] = 0
+    fronta = deque()
+    fronta.append(v0)
+
+    while fronta:
+        u = fronta.popleft()
+        print(u, vzdalenost[u])
+        for v in graf.sousede(u):
+            if not byl_jsem[v]:
+                byl_jsem[v] = True
+                vzdalenost[v] = vzdalenost[u] + 1
+                fronta.append(v)
+
+prohledej(3)
diff --git a/09-grafy/do-sirky-matice.py b/09-grafy/do-sirky-matice.py
new file mode 100755
index 0000000000000000000000000000000000000000..af3b3675fd5cdd23f3f792bcb98c07ce3980a0ad
--- /dev/null
+++ b/09-grafy/do-sirky-matice.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python3
+# Prohledávání grafu do šířky
+# Graf je reprezentovaný pomocí matice sousednosti
+
+from pprint import pprint
+from collections import deque
+
+# Načteme vstup: nejprve počet vrcholů, pak n řádků se sousedy jednotlivých vrcholů
+n = int(input())
+matice = [[0]*n for _ in range(n)]
+for i in range(n):
+    for j in input().split():
+        j = int(j)
+        matice[i][j] = 1
+
+# Pro kontrolu vypíšeme reprezentaci grafu (pprint = pretty print)
+pprint(matice)
+
+# Prohledávání do šířky
+def prohledej(v0):
+    byl_jsem = [False] * n
+    byl_jsem[v0] = True
+    vzdalenost = [None] * n
+    vzdalenost[v0] = 0
+    fronta = deque()
+    fronta.append(v0)
+
+    while fronta:
+        u = fronta.popleft()
+        print(u, vzdalenost[u])
+        for v in range(n):
+            if matice[u][v] == 1 and not byl_jsem[v]:
+                byl_jsem[v] = True
+                vzdalenost[v] = vzdalenost[u] + 1
+                fronta.append(v)
+
+prohledej(3)
diff --git a/09-grafy/do-sirky-seznamy.py b/09-grafy/do-sirky-seznamy.py
new file mode 100755
index 0000000000000000000000000000000000000000..526a4cf1c88d46605eb0616707b6850c3409b564
--- /dev/null
+++ b/09-grafy/do-sirky-seznamy.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python3
+# Prohledávání grafu do šířky
+# Graf je reprezentovaný pomocí seznamů sousedů
+
+from collections import deque
+
+# Načteme vstup: nejprve počet vrcholů, pak n řádků se sousedy jednotlivých vrcholů
+n = int(input())
+sousede = []
+for i in range(n):
+    sousede.append([ int(j) for j in input().split() ])
+
+# Pro kontrolu vypíšeme reprezentaci grafu
+print(sousede)
+
+# Prohledávání do šířky
+def prohledej(v0):
+    byl_jsem = [False] * n
+    byl_jsem[v0] = True
+    vzdalenost = [None] * n
+    vzdalenost[v0] = 0
+    fronta = deque()
+    fronta.append(v0)
+
+    while fronta:
+        u = fronta.popleft()
+        print(u, vzdalenost[u])
+        for v in sousede[u]:
+            if not byl_jsem[v]:
+                byl_jsem[v] = True
+                vzdalenost[v] = vzdalenost[u] + 1
+                fronta.append(v)
+
+prohledej(3)
diff --git a/09-grafy/iterator.py b/09-grafy/iterator.py
new file mode 100755
index 0000000000000000000000000000000000000000..3694179d3d981e6e7d88c60f8c18e53f6a8636c2
--- /dev/null
+++ b/09-grafy/iterator.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python3
+# Příklad na iterátory: vlastní implementace range(n)
+
+class MyRange:
+
+    def __init__(self, n):
+        self.n = n
+
+    # Touto magickou metodou objektu řekneme, aby vyrobil iterátor
+    def __iter__(self):
+        return MyIter(self)
+
+class MyIter:
+
+    # Iterátoru při inicializaci říkáme, ke kterému MyRange patří
+    def __init__(self, rng):
+        # Iterátor si pamatuje range a poslední vygenerované číslo
+        self.rng = rng
+        self.i = -1
+
+    # Touto magickou metodou po iterátoru chceme, aby vydal další prvek,
+    # nebo vyvolal výjimku StopIteration, pokud už žádný další neexistuje.
+    def __next__(self):
+        self.i += 1
+        if self.i < self.rng.n:
+            return self.i
+        else:
+            raise StopIteration
+
+for x in MyRange(10):
+    print(x)
+
+# Uvnitř for-u se stane toto:
+#
+#   r = MyRange(10)
+#   it = r.__iter__()    <- řekneme objektu MyRange, aby vyrobil iterátor
+#   while True:
+#       x = it.__next__()   <- řekneme iterátoru, aby vydal další prvek
+#       pokud nastala výjimka StopIteration, skonči
+#       print(x)         <- tělo cyklu
diff --git a/09-grafy/test.in b/09-grafy/test.in
new file mode 100644
index 0000000000000000000000000000000000000000..d3f40aa8691135f8081860aac82dd1496c181b30
--- /dev/null
+++ b/09-grafy/test.in
@@ -0,0 +1,6 @@
+5
+1
+2
+3
+1 4
+