Vous êtes sur la page 1sur 57

Univerzitet u Novom Sadu

Prirodno-matematički fakultet
Departman za matematiku i informatiku

Dragan Mašulović

Diskretne strukture 2
Deo 4: Teorija grafova

Novi Sad, 2018.


2
Glava 1

Grafovi

Grafovi predstavljaju jedno od najpopularnijih sredstava za modelovanje dis-


kretnih fenomena kod kojih je potrebno predstaviti informaciju o tome da li su
izvesni objekti u vezi ili ne, na primer, raskrsnice i ulice u nekom gradu, ili auto-
putevi i gradovi u nekoj državi.

1.1 Osnovni pojmovi


Graf je uredeni par G =  (V, E), gde je V neprazan
konačan skup, a E proizvo-
ljan podskup skupa V (2) = {u, v} ⊆ V : u 6= v . Elemente skupa V zovemo čvorovi
grafa G, dok elemente skupa E zovemo grane grafa G. Često ćemo skup čvorova i
skup grana grafa G označavati sa V (G) i E(G), a broj čvorova i broj grana grafa G
sa n(G) i m(G). Ako je e = {u, v} grana grafa, kažemo da su u i v susedni, i da je
grana e incidentna sa u i v. Takode kažemo da je čvor u sused čvora v. Skup suseda
čvora v je skup NG (v) = {x ∈ V (G) : x je sused čvora v}. Stepen čvora v, u oznaci
δG (v), je broj grana grafa koje su incidentne sa v: δG (v) = |NG (v)|. Ako se graf
G podrazumeva, pišemo N(v) i δ (v). Sa δ (G) označavamo najmanji, a sa ∆(G)
najveći stepen čvora u grafu G. Za čvor stepena 0 kažemo da je izolovan, a za čvor
stepena 1 da je viseći čvor u G. Za čvor kažemo da je paran, odnosno neparan
u zavisnosti od toga da li je δ (v) paran ili neparan broj. Graf je regularan ako je
δ (G) = ∆(G). Drugim rečima, graf je regularan ako svi njegovi čvorovi imaju isti
stepen.
Grafovi se zovu grafovi zbog veoma prirodne grafičke reprezentacije koja je
postala uobičajen način komunikacije medu ljudima koji se bave grafovima. Čvo-
rove predstavljamo kružićima u ravni, a grane glatkim krivim bez samopreseka
koje spajaju odgovarajuće čvorove.

1
2 GLAVA 1. GRAFOVI

s t viseći čvor
izolovani
čvor ovo nije čvor

u
w
y grana
x

v
z
N(v)

Slika 1.1: Primer grafa

Primer 1.1 Na Sl. 1.1prikazan je graf G sa skupom čvorova V = {s,t, u, v, w, x, y, z}


i skupom grana E = {t, u}, {u, x}, {u, v}, {w, y}, {w, v}, {v, x}, {v, y}, {v, z},
{x, y}, {x, z}, {y, z} . Vidimo da je

čvor s t u v w x y z
δ 0 1 3 5 2 4 4 3
pa je δ (G) = 0 i ∆(G) = 5. Takode, N(v) = {u, w, x, y, z}.

Teorema 1.2 (Prva teorema teorije grafova) Ako je G = (V, E) graf sa m grana,
onda je ∑ δ (v) = 2m.
v∈V

Dokaz. Kako je svaka grana incidentna sa dva čvora, svaka grana je prebrojana dva
puta u sumi na levoj strani jednakosti. 

Primer 1.3 U jednoj sali se nalazi 77 ljudi. Da li je moguće da svaki od njih


poznaje tačno 7 drugih?
Predstavimo ovu situaciju grafom tako da ljude predstavimo čvorovima grafa,
a dva čvora su susedni u tom grafu ako i samo ako se odgovarajući ljudi poznaju.
Tako pitanje postaje: Da li postoji graf sa 77 čvorova u kome svaki čvor ima ste-
pen 7?
Odgovor: ne. Pretpostavimo da takav graf postoji i neka on ima m grana.
Prema prvoj teoremi je
7| + 7 +
{z· · · + 7} = 2m
77
1.1. OSNOVNI POJMOVI 3

odnosno, 7 · 77 = 2m, što je nemoguće jer je broj na levoj strani neparan, dok je
broj na desnoj strani paran.

Zapravo, važi mnogo opštiji rezultat:

Posledica 1.4 U svakom grafu broj neparnih čvorova je paran.

Graf H = (W, E ′ ) je podgraf grafa G = (V, E), pišemo H 6 G, ako je W ⊆ V i


E ′ ⊆ E. Podgraf H grafa G je pokrivajući podgraf grafa G ako je W = V (G). Graf
H je indukovani podgraf grafa G ako je E ′ = E ∩W (2) . Indukovani podgraf ćemo
označavati sa G[W ]. Grane indukovanog podgrafa grafa G su sve grane grafa G
čija oba kraja pripadaju skupu W .

K7 C9 P6

Slika 1.2: K7 , C9 i P6

Kompletan graf sa n čvorova (ili n-klika) je graf sa n čvorova kod koga su


svaka dva različita čvora susedna. Kompletan graf sa n čvorova označavamo sa
Kn . Kontura sa n čvorova, u oznaci Cn , je graf sa n čvorova kod koga je prvi čvor
susedan sa drugim, drugi sa trećim, i tako dalje, poslednji čvor je susedan sa prvim.
Put sa n čvorova, u oznaci Pn , je graf kod koga je prvi čvor susedan sa drugim,
drugi sa trećim, i tako dalje, pretposlednji susedan sa poslednjim, a poslednji nije
susedan sa prvim. Kažemo da put sa n čvorova ima dužinu n − 1. Na Sl. 1.2 su
prikazani K7 , C9 i P6 .

Teorema 1.5 Ako je δ (G) > 2, graf G sadrži konturu.

Dokaz. Neka je x1 . . . xk−1 xk najduži put u G. Pošto je δ (xk ) > δ (G) > 2, čvor
xk ima suseda v koji nije xk−1 . Ako v ∈ / {x1 , . . . , xk−2 } onda je x1 . . . xk−1 xk v
put koji je duži od najdužeg puta u G, što je nemoguće. Dakle, v = x j za neko
j ∈ {1, . . . , k − 2}, pa su x j . . . xk čvorovi konture u G. 
4 GLAVA 1. GRAFOVI

1.2 Reprezentacija grafa


Postoji nekoliko načina reprezentacije grafova, a mi ćemo pokazati dva:
• reprezentaciju preko matrice susedstva, i

• reprezentaciju preko listi suseda.


U reprezentacijama koje ćemo ovde razmatrati skup čvorova grafa će uvek biti
{0, 1, . . . , n − 1}. Klasa Graf je osnovna klasa koja opisuje grafove. Ona ima
konstruktor Graf(int n) koji konstruiše prazan graf sa n čvorova, i konstruktor
Graf(String fname) koji učitava opis grafa iz tekstualne datoteke fname. Metodi
brCvorova() i brGrana() vraćaju broj čvorova, odnosno, broj grana grafa G, dok
metod deg(int v) vraća stepen čvora v u grafu. Metod susedni(int u, int v) vraća
true ako i samo ako su čvorovi u i v susedni. Metod dodajGranu(int u, int v)
grafu G dodaje novu granu izmedu čvorova u i v za koje se zna da su nesusedni,
dok metod ukloniGranu(int u, int v) iz grafa G uklanja granu {u, v} pri čemu se
pretpostavlja da su u i v susedni u G.
public class Graf {

public final static int NoVertex = −1;

private int N; // broj cvorova grafa


private int M; // broj grana grafa
... // jos neka polja koja zavise od reprezentacije

public Graf(String fname) { ... }


public Graf(int n) { ... }

public int brCvorova() { return N; }


public int brGrana() { return M; }
public int deg(int v) { ... }

public boolean susedni(int u, int v) { ... }

public void dodajGranu(int u, int v){ ... }


public void ukloniGranu(int u, int v){ ... }

Često ćemo imati potrebu da prodemo kroz skup svih suseda nekog čvora u
grafu. Da bismo olakšali i automatizovali taj posao, uvešćemo klasu SkupSuseda
koja predstavlja (veoma primitivan) iterator po skupu suseda čvora u grafu. Metod
1.2. REPREZENTACIJA GRAFA 5

susedi(int v) inicijalizuje iterator S tako što ga napuni podacima o skupu suseda


čvora v. Metod sledeci(SkupSuseda S) vraća sledeći čvor sa spiska koji je predsta-
vljen iteratorom S, a metod imaJos(SkupSuseda S) proverava da li u skupu suseda
opisanom iteratorom S ima još čvorova.
public SkupSuseda susedi(int v) { ... }
public boolean imaJos(SkupSuseda S) { ... }
public int sledeci(SkupSuseda S) { ... }

Reprezentacije grafa se razlikuju po tome kako organizujemo podatke da upam-


timo incidentnu strukturu grafa, i po tome kako su implementirane navedene me-
tode.

Primer 1.6 Evo primera programa koji učitava graf G i potom za svaki čvor tog
grafa štampa njegov stepen i spisak svih njegovih suseda.

public class GrTest1 {


public static void main(String args []) {
Graf G = new Graf(”test1.txt ” );
System.out.println ( ”Broj cvorova = ” + G.brCvorova());
System.out.println ( ”Broj grana = ” + G.brGrana());
for( int i = 0; i < G.brCvorova(); i++){
System.out.println ( ”deg(” + i + ” ) = ” + G.deg(i ));
System.out.print( ”susedi: ” );
SkupSuseda S = G.susedi(i);
while(G.imaJos(S)){
int x = G.sledeci(S);
System.out.print(x + ” ” );
}
System.out.println ();
}
}
}
6 GLAVA 1. GRAFOVI

1.2.1 Matrica susedstva


Prvi način reprezentacije grafova koga ćemo pomenuti i koga ćemo najčešće
koristiti se zasniva na tome da se graf predstavi preko svoje matrice susedstva.
Neka je G graf sa skupom čvorova {0, 1, . . . , n − 1}. Tada je matrica susedstva
grafa G (engl. adjacency matrix), u oznaci A(G), matrica [ai j ] formata n × n takva
da je (
0, čvorovi i i j nisu susedni,
ai j =
1, čvorovi i i j su susedni.
Ako je čvor u susedan sa čvorom v, onda je i čvor v susedan sa čvorom u, tako da
je matrica A(G) uvek simetrična. Primer je dat na Slici 1.3.
Klasu SkupSuseda ćemo implementirati tako da sadrži dva polja: čvor v kroz
čije susede iteriramo, i indeks i koji sadrži redni broj narednog suseda čvora v.
public class SkupSuseda {
public int v, i ;
public SkupSuseda(int vv, int ii ) { v = vv; i = ii ; }
}

Svaka instanca klase Graf ima četiri polja: N – broj čvorova grafa, M – broj
grana grafa, D – niz stepena čvorova grafa, i A – matrica susedstva grafa.
public class Graf {
public final static int NoVertex = −1;
private int N; // broj cvorova grafa
private int M; // broj grana grafa
private int [] D; // stepen cvora
private int [][] A; // matrica susedstva

Implementacija konstruktora i metoda je jednostavna:

public Graf(String fname) {


try {
SimpleIO.openFileInput(fname);
N = SimpleIO.rdInt (); D = new int[N]; A = new int[N][N];
int sum = 0;
for( int i = 0; i < N; i++){
int s = 0;
for( int j = 0; j < N; j++){
A[i ][ j ] = SimpleIO.rdInt ();
if (A[i ][ j ] != 0) s++;
1.2. REPREZENTACIJA GRAFA
A(G) 0 1 2 3 4 5 6 7 8 9 10 11 12
0 0 0 0 0 0 0 0 0 0 0 0 0 0
8 11 1 0 0 1 0 0 0 0 0 0 0 0 0 0
12 2 0 1 0 0 0 1 0 0 0 0 1 0 0
4 3 0 0 0 0 1 1 1 1 1 0 0 0 0
10 4 0 0 0 1 0 0 0 0 0 1 0 0 0
5 0 0 1 1 0 0 0 0 1 1 0 1 0
3
G= 6 0 0 0 1 0 0 0 0 0 1 0 0 0
5 7 0 0 0 1 0 0 0 0 0 0 1 0 0
9 2 8 0 0 0 1 0 1 0 0 0 0 0 0 0
6 9 0 0 0 0 1 1 1 0 0 0 0 0 0
7 10 0 0 1 0 0 0 0 1 0 0 0 0 1
11 0 0 0 0 0 1 0 0 0 0 0 0 1
0 1 12 0 0 0 0 0 0 0 0 0 0 1 1 0

Slika 1.3: Graf i njegova matrica susedstva

7
8 GLAVA 1. GRAFOVI

}
D[i ] = s; sum += s;
}
M = sum / 2;
} catch (FileNotFoundException fn) {
System.out.println ( ” File not found: ” + fn );
} catch (Exception ex) {
System.out.println (ex);
}
SimpleIO.closeInput();
}

public Graf(int n) {
N = n; M = 0; D = new int[N]; A = new int[N][N];
for( int i = 0; i < N; i++){
for( int j = 0; j < N; j++) A[i ][ j ] = 0;
D[i ] = 0;
}
}

public int brCvorova() { return N; }

public int brGrana() { return M; }

public int deg(int v) { return D[v]; }

public void dodajGranu(int u, int v){


D[u]++; D[v]++; M++; A[u][v] = 1; A[v ][ u] = 1;
}

public void ukloniGranu(int u, int v){


D[u]−−; D[v]−−; M−−; A[u][v] = 0; A[v][u] = 0;
}

public boolean susedni(int u, int v) { return A[u][v] != 0; }


1.2. REPREZENTACIJA GRAFA 9

private void nadjiSledeciCvor(SkupSuseda S) {


while(true) {
S.i++;
if (S.i >= N) break;
if (susedni(S.v, S.i )) break;
}
}

public SkupSuseda susedi(int v) {


SkupSuseda S = new SkupSuseda(v, NoVertex);
nadjiSledeciCvor(S);
return S;
}

public boolean imaJos(SkupSuseda S) { return S.i < N; }

public int sledeci(SkupSuseda S) {


int v = S.i ;
nadjiSledeciCvor(S);
return v;
}

1.2.2 Liste suseda


Grafovi se na drugi način mogu predstaviti pomoću dva niza: niz list za svaki
čvor sadrži spisak njegovih suseda (to je lista suseda), dok niz idx u polju j sadrži
početak spiska suseda čvora j. Pri tome, ako graf ima n čvorova, polje idx [n]
pokazuje na prvo slobodno polje niza list .

Primer 1.7 Primer grafa i njegove reprezentacije preko listi suseda dati su na
Sl. 1.4. Sa idx [0] = 0 smo označili da spisak suseda čvora broj 0 počinje od in-
deksa 0 niza list ; sa idx [1] = 2 smo označili da spisak suseda čvora broj 1 počinje
od indeksa 2 u nizu list ; i tako dalje. Zato što graf ima šest čvorova, popunjeno
je i polje idx [6] , a vrednost tog polja je 12 zato što 12 predstavlja indeks prvog
slobodnog polja u nizu list .

Sada ćemo grafove predstavljati kao slogove koji imaju četiri polja: N – broj
čvorova grafa, M – broj grana grafa, idx – niz indeksa, i list – liste suseda.
10 GLAVA 1. GRAFOVI

0 1 2

3 4 5

0 1 2 3 4 5 6
idx 0 2 5 6 8 11 12

list 1 3 0 3 4 4 0 1 1 2 5 4

Slika 1.4: Graf i njegova reprezentacije preko listi suseda

public class GrafLS {


public final static int NoVertex = −1;
private int N; // broj cvorova grafa
private int M; // broj grana grafa
private int [] idx ; // lista indeksa
private int [] list ; // lista suseda

public int deg(int v) { return idx [v + 1] − idx[v ]; }

public boolean susedni(int u, int v) {


for( int i = idx [u ]; i < idx[u + 1]; i ++) {
if ( list [ i ] == v) return true;
}
return false;
}

// itd

Menja se i rad sa iteratorima, koji u ovoj implementacije postaje efikasniji:


public SkupSuseda susedi(int v) {
return new SkupSuseda(v, idx[v]);
}

public boolean imaJos(SkupSuseda S) { return S.i < idx[S.v + 1]; }


1.3. IZOMORFIZAM GRAFOVA 11

public int sledeci(SkupSuseda S) {


int v = list [S.i ];
S.i++;
return v;
}

Primetimo da nam je za reprezentaciju grafa preko matrice susedstva potreban


memorijski prostor veličine O(n2 ), gde je n broj čvorova grafa, dok nam je za
reprezentaciju preko listi suseda dovoljan memorijski prostor veličine O(m + n),
gde je m broj grana grafa.
Izbor reprezentacije grafa zavisi od toga da li imamo dodatnu informaciju o
broju grana ili ne. Ako nemamo gornje ograničenje na broj grana, onda ćemo uvek
birati reprezentaciju preko matrice susedstva. Ako, medutim, znamo da će broj
grana imati neku unapred zadatu gornju granicu i ako je tada m + n dovoljno manje
od n2 , opredelićemo se za reprezentaciju preko listi suseda.
Osim toga, odluka o izboru reprezentacije zavisi i od operacija koje treba da
obavljamo nad grafom. Ponekad ćemo se i u slučaju grafova sa relativno malim
brojem grana opredeliti za reprezentaciju preko matrice susedstva ako se operacije
koje treba da obavimo nad grafom ne mogu efikasno implementirati u reprezenta-
ciji preko listi suseda. Naravno, važi i obrnuto.

1.3 Izomorfizam grafova


Često se dešava da dva, na prvi pogled različita grafa, predstavljaju zapravo
jedan isti sistem veza. Na primer, grafovi G1 i G2 na Sl. 1.5 predstavljaju isti
sistem veza, što nije slučaj sa grafovima G2 i G3 na istoj slici. Pojam izomorfizma
grarfova je formalni koncept koji nam omogućuje da preciziramo ovu intuiciju.
Grafovi G1 i G2 su izomorfni ako postoji bijekcija ϕ : V (G1 ) → V (G2 ) takva
da je {x, y} ∈ E(G1 ) ⇔ {ϕ (x), ϕ (y)} ∈ E(G2 ). Za bijekciju ϕ kažemo da je izo-
morfizam. Pišemo G1 ∼ = G2 .

Primer 1.8 Grafovi G1 i G2 na Sl. 1.5 su izomorfni jer je


 
a b c d p q
ϕ=
3 4 1 5 2 6

bijekcija iz V (G1 ) u V (G2 ) koja ima navedenu osobinu.


Da bismo pokazali da dva grafa nisu izomorfni, treba da nademo neku grafov-
sku osobinu koju jedan graf poseduje, a drugi ne. Grafovi G2 i G3 na Sl. 1.5 nisu
12 GLAVA 1. GRAFOVI

izomorfni zato što graf G2 ima konturu C4 kao indukovani podgraf, što nije slučaj
sa grafom G3 .

3 3
q
b p 4
d
1 2 1 2

c
5 6 4 5 6
G1 G2 G3

Slika 1.5: Tri grafa

Teorema 1.9 Neka je G1 ∼ = G2 i neka je ϕ proizvoljan izomorfizam ta dva grafa.


Tada je n(G1 ) = n(G2 ), m(G1 ) = m(G2 ) i δG1 (x) = δG2 (ϕ (x)) za svako x ∈ V (G1 ).

Zadaci za vežbu
1.1. Dokazati da graf sa n čvorova može imati najviše 12 n · (n − 1) grana.
1.2. Neka je G graf sa n čvorova i n−1 grana. Dokazati da u G postoji izolovani
ili viseći čvor.
2m
1.3. Neka je G graf sa n čvorova i m grana. Dokazati da je ∆(G) > .
n
1.4. Koji od sledećih nizova mogu da se pojave kao nizovi stepena čvorova
nekog grafa?
(a) (1, 2, 2, 4, 5, 6, 7);
(b) (1, 1, 2, 2, 2, 3, 3);
(c) (1, 1, 3, 3, 3, 3, 5, 6, 8, 9).
1.5. Ako je n(G) > 2, onda postoje čvorovi v, w ∈ V (G) takvi da je v 6= w i
δ (v) = δ (w). Dokazati.
1.6. Za svako n > 2 postoji graf sa n čvorova u kome tačno jedan par čvorova
ima isti stepen. Dokazati.
ZADACI ZA VEŽBU 13

1.7. Neka je G graf u kome ne postoje dva čvora istog stepena koji imaju za-
jedničkog suseda. Dokazati da G ima viseći čvor.
†1.8. Neka je V = {1, 2, . . . , n}. Dokazati da ima
n
2
(a) 2 različitih grafova sa skupom čvorova V ;
n−1

2
(b) 2 različitih grafova sa skupom čvorova V čiji svi čvorovi su parni.
1.9. Neka je G graf sa osobinom δ (G) > 2. Dokazati da G sadrži put dužine
> δ (G) i konturu dužine > δ (G) + 1.
1.10. Za svaki graf G postoji regularan graf H takav da je G indukovani podgraf
grafa H i ∆(G) = ∆(H). Dokazati.
1.11. Klasi Graf dodati metode public int minDeg() koji odreduje minimalni
stepen grafa, i public int maxDeg() koja odreduje maksimalni stepen grafa.
1.12. Napisati Java program koji učitava graf i potom za svaki čvor u grafu
odreduje sumu stepena svih njegovih suseda, kao i srednju vrednost te
sume.
1.13. Implementirati preostale procedure u reprezentaciji grafova preko lista su-
seda.
14 GLAVA 1. GRAFOVI
Glava 2

Povezanost i rastojanje

Za graf kažemo da je povezan ako se od svakog čvora tog grafa može stići do
svakog drugog čvora grafa krećući se pri tome samo po granama grafa. Povezanost
je veoma važno svojstvo grafa i zato je važno imati efikasan algoritam koji se ono
proverava. Takav algoritam postoji, krajnje je jednostavan i svodi se na to da na
neki sistematski način obidemo svaki čvor grafa. Postoje dva standardna načina
obilaska čvorova grafa:

• pretraživanjem u dubinu (depth-first search – skraćeno DFS), i

• pretraživanjem u širinu (breadth-first search – skraćeno BFS).

U prvom odeljku ove glave uvešćemo pojam povezanosti grafa, DFS algori-
tam, i pokazati kako se povezanost može lako utvrditi upotrebom DFS algoritma.
U drugom odeljku ćemo uvesti pojam rastojanja na povezanim grafovima, BFS
algoritam, i videti da se rastojanje dva čvora u grafu može lako dobiti upotrebom
BFS algoritma.

2.1 Povezanost i DFS


Šetnja u grafu G je svaki niz čvorova i grana v0 e1 v1 e2 v2 . . . vk−1 ek vk kod koga
je ei = {vi−1 , vi } za sve i ∈ {1, . . . , k}. Primetimo da se jedan čvor ili grana može
više puta pojaviti u šetnji. Kažemo da je k dužina šetnje. Ako je v0 6= vk kažemo
da šetnja povezuje v0 sa vk . Zatvorena šetnja je šetnja v0 e1 v1 . . . vk−1 ek vk kod
koje je v0 = vk . Primetimo da je put šetnja kod koje se ne ponavljaju ni čvorovi ni
grane, a kontura je zatvorena šetnja kod koje se ne ponavljaju ni čvorovi ni grane,
osim prvog čvora koji se pojavljuje na kraju šetnje. Očigledno važi sledeće:

15
16 GLAVA 2. POVEZANOST I RASTOJANJE

Lema 2.1 Ako postoji šetnja u G koja povezuje dva čvora, onda postoji i put koji
ih povezuje.
Dokaz. Neka su u i w različiti čvorovi grafa G takvi da postoji šetnja koja ih
povezuje. Dokažimo da onda postoji i put koji ih povezuje. Od svih šetnji koje
povezuju u i w uočimo najkraću, i neka je to šetnja

u = v0 e1 v1 e2 v2 . . . vk−1 ek vk = w.

Ako u ovoj šetnji postoje i i j takvi da je i < j i vi = v j :


vj
v0 v1 vi v j+1 vk

v j−1 vi+1

onda je u = v0 e1 v1 e2 . . . vi e j+1 v j+1 . . . vk−1 ek vk = w kraća šetnja koja povezuje


| {z }
preskočimo
deo šetnje
od vi do v j
u sa w, što je nemoguće. Dakle, svi čvorovi u najkraćoj šetnji su različiti, što znači
da to mora biti put. 

Teorema 2.2 Neka je G graf. Na skupu V (G) definišemo binarnu relaciju θ ovako:
xθ y ako x = y ili postoji šetnja koja spaja x sa y. Tada je θ relacija ekvivalencije na
V (G).
Kao i svaka druga relacija ekvivalencije, relacija θ razbija skup V (G) na blo-
kove S1 , . . . , St . Ove blokove, ili odgovarajuće indukovane podgrafove (kako nam
kad više odgovara) zovemo komponente povezanosti grafa G. Broj komponenti
povezanosti grafa G označavamo sa cc(G). Graf G je povezan ako je cc(G) = 1.
Primer povezanog grafa i primer grafa sa četiri komponente povezanosti dati su na
Sl. 2.1.
Da bismo mogli algoritamski da identifikujemo komponente nekog grafa, po-
trebno je da imamo sistematski način obilaženja čvorova tog grafa. Pretraživanje u
dubinu (depth-first search) je jedan veoma elegantan način da se to uradi: krenuvši
od nekog čvora u grafu, za svakog suseda tog čvora koga do sada nismo posetili
rekurzivno pozovemo algoritam. Dakle, posetimo polazni čvor, potom posetimo
njegovog prvog suseda, pa prvog suseda prvog suseda, i tako u dubinu dokle god
2.1. POVEZANOST I DFS 17

(a) (b)

Slika 2.1: (a) Povezan graf; (b) Graf G kod koga je cc(G) = 4

je to moguće. Kada se vratimo iz rekurzivnog poziva, proverimo da li je neki sused


tekućeg čvora ostao neposećen. Ako jeste, spustimo se na tu stranu sve dok može.
Nastavljamo na ovaj način dok ne posetimo sve čvorove koji se DFS algoritmom
mogu dosegnuti iz polaznog čvora.
Konkretna implementacija algoritma koristi klasu TimeStamps koja je veoma
jednostavna. Polje N predstavlja “diskretno vreme”. Ono se u svakom koraku
uvećava za 1 i tu vrednost dodeljujemo elementima niza stamp. Tako svaki čvor
dobija time-stamp. U nizu stamp pamtimo kojim redom smo posetili koji čvor:
stamp[v] == k ako i samo ako smo u trenutku T = k posetili čvor v. Takode, ovaj
niz nam treba i da bismo mogli da utvrdimo da li smo neki čvor već posetili. Zato
ga inicijalizujemo tako da je pre početka rada DFS procedure stamp[v] == 0 za sve
čovore grafa. Sada znamo da smo čvor v posetili ako i samo ako je stamp[v] != 0.
public class TimeStamps {
public int N;
public int [] stamp;

public TimeStamps(int k, int val) {


N = 0;
stamp = new int[k];
for( int i = 0; i < k; i ++) stamp[i] = val ;
}
}

Metod DFS klase Graf koji obilazi čvorove grafa G počev od čvora v izgleda
ovako:
18 GLAVA 2. POVEZANOST I RASTOJANJE

// metod klase Graf; poziva se ovako: G.DFS(v, dft)


public void DFS(int v, TimeStamps dft) {
dft .N++;
dft .stamp[v] = dft .N;
SkupSuseda S = susedi(v);
while(imaJos(S)){
int w = sledeci(S);
if ( dft .stamp[w] == 0) DFS(w, dft);
}
}

Primer 2.3 Na slici pored dat je


graf i dat je redosled obilaska nje-
1 b
govih čvorova ukoliko se DFS al-
goritam startuje od čvora b. Prvo
posetimo čvor b; potom njegovog 3 6
prvog suseda, a; potom prvog su- c f
seda čvora a što je c; onda prvog 2
a
suseda čvora c što je d itd. sve do
h. U povratku iz rekurzije, kada
dodemo do c primetićemo da su-
8 4 5 7
sed g čvora c nije posećen, tako g d e h
da ćemo sada posetiti i njega, i na
kraju se vratiti sasvim iz rekurzije
završivši time obilazak.
Primer 2.4 Ako pustimo algori-
tam DFS na graf na slici pored
1 b
počev od čvora b, dobićemo redo-
sled obilazaka čvorova koji je na-
značen na slici. Primećujemo da 3 0
postoje čvorovi koje nismo pose- c f
tili. Algoritam nije imao načina 2
a
da dode do čvorova g, f i h zato
što ne postoji put od b do nekog
od njih. Dakle, DFS može da po-
0 4 5 0
seti samo one čvorove koji se na- g d e h
laze u istoj komponenti povezano-
sti kao i čvor od koga smo krenuli
sa pretraživanjem.
2.1. POVEZANOST I DFS 19

Sada ćemo dokazati ovu važnu osobinu algoritma DFS. Krenimo sa jednim
pomoćnim tvrdenjem.

Lema 2.5 Neka je G graf nad kojim je izvršenja procedura DFS i neka je na taj
način dobijen niz stamp. Ako je dft .stamp[v] != 0 za neko v ∈ V (G), onda je
dft .stamp[w] != 0 za svakog suseda w čvora v.

Dokaz. Ovo je direktna posledica strukture DFS procedure: while-ciklus u telu


procedure prode kroz spisak svih suseda čvora v i za svakog suseda w za koga je
dft .stamp[w] == 0 realizuje se rekurzivni poziv DFS(w, dft) u kom će dft .stamp[w]
dobiti neku pozitivnu vrednost. Dakle, kada se završi while-ciklus u telu DFS
procedure, za svakog suseda w čvora v važi dft .stamp[w] != 0. 

Teorema 2.6 Neka je G graf, neka je v ∈ V (G) proizvoljno i neka je nad G izvršena
procedura DFS(v, dft) . Tada za svaki x ∈ V (G) važi sledeće: dft .stamp[x] != 0 ako
i samo ako x pripada komponenti povezanosti čvora v. Drugim rečima, DFS(v, dft)
može da dosegne samo one čvorove koji pripadaju komponenti povezanosti čvora v.
Dokaz. (⇒) Ako je dft .stamp[x] != 0 to znači da je algoritam u nizu rekurzivnih
poziva stigao od čvora v do čvora x. Obzirom da algoritam u svakom koraku prelazi
sa čvora na njemu susedni čvor koga do tada nije posetio, dobijamo da postoji put
od v do x, što znači da x pripada komponenti povezanosti čvora v.
(⇐) Neka x pripada komponenti povezanosti čvora v. Tada postoji šetnja
v e1 v1 e2 v2 . . . ek−1 vk−1 ek x. Nad grafom G je izvršena procedura DFS(v, dft) ,
što znači da je dft .stamp[v ] == 1. Prema Lemi 2.5 je dft .stamp[v1 ] != 0 zato što
je v1 susedan sa v. Na isti način zaključujemo da je dft .stamp[v2 ] != 0 zato što je
v2 susedan sa v1 . I tako dalje. Na kraju dobijamo da je dft .stamp[x ] != 0 zato što
je x susedan sa vk−1 . 

Posledica 2.7 Neka je G graf, neka je v ∈ V (G) proizvoljno i neka je nad G


izvršena procedura DFS(v, dft) . Graf G je povezan ako i samo ako je dft .stamp[x] != 0
za sve x ∈ V (G).
Na osnovu ove posledice dobijamo jednostavan i veoma efikasan algoritam koji
proverava da li je graf povezan:

// metod klase Graf; poziva se ovako: G.povezan()


public boolean povezan() {
TimeStamps dft = new TimeStamps(N, 0);
DFS(0, dft );
20 GLAVA 2. POVEZANOST I RASTOJANJE

for( int i = 0; i < N; i++){


if ( dft .stamp[i] == 0) return false;
}
return true;
}

kao i jednostavan i efikasan algoritam koji broji komponente povezanosti grafa:

// metod klase Graf; poziva se ovako: G.brKompPovez()


public int brKompPovez() {
int k = 0;
TimeStamps dft = new TimeStamps(N, 0);
for( int i = 0; i < N; i++){
if ( dft .stamp[i] == 0) {
k++;
DFS(i, dft );
}
}
return k;
}

Jednostavnom modifikacijom gornjeg algoritma dobijamo algoritam koji raz-


vrstava cvorove grafa po komponentama povezanosti. Metod komponentePovez
vraća niz celih brojeva u koji za svaki čvor grafa sadrži redni broj komponente po-
vezanosti kojoj taj čvor pripada. Za ovu proceduru je potrebno modifikovati pro-
ceduru DFS: umesto da uvećava interni brojač i čvorove označava tako dobijenim
brojem, modifikovanoj verziji metoda DFS se prosleduje broj kojim treba označiti
čvorove (a to je redni broj komponente povezanosti kojoj ti čvorovi pripadaju).
public void DFS(int v, TimeStamps dft, int stamp) {
dft .stamp[v] = stamp;
SkupSuseda S = susedi(v);
while(imaJos(S)){
int w = sledeci(S);
if ( dft .stamp[w] == 0) DFS(w, dft, stamp);
}
}

public int [] komponentePovez() {


int k = 0;
TimeStamps dft = new TimeStamps(N, 0);
2.2. RASTOJANJE I BFS 21

for( int i = 0; i < N; i++){


if ( dft .stamp[i] == 0) {
k++;
DFS(i, dft , k );
}
}
return dft .stamp;
}

2.2 Rastojanje i BFS


Pretraživanje u širinu (breadth-first search) predstavlja drugi standardan način
da obidemo sve čvorove grafa: krenemo od proizvoljnog čvora u grafu, onda
obidemo sve njegove susede, pa sve susede od prvog suseda polaznog čvora, potom
sve susede drugog suseda polaznog čvora, i tako dalje.

Primer 2.8 Na slici pored dat je graf


1 b
i dat je redosled obilaska njegovih
čvorova ukoliko se BFS algoritam star-
tuje od čvora b. Prvo posetimo čvor 3 4
c f
b; potom njegove susede, a, c i f ; po- 2
tom susede čvora a koje do sada ni- a
smo obišli, a to su d i e; potom susede
čvora c koje do sada nismo obišli, a to
je g; i na kraju susede čvora f koje do 7 5 6 8
g d e h
sada nismo obišli, a to je samo h.

Šematski prikaz redosleda obilaska čvorova grafa na Sl. 2.2 (a) BFS algorit-
mom prikazn je na Sl. 2.2 (b).
Implementacija BFS algoritma se oslanja na standardnu strukturu podataka
koja se zove red za čekanje (engl. queue). Red za čekanje je linearna struktura
podataka kod koje nove elemente dodajemo na kraj reda, a postojeće elemente ski-
damo sa početka reda. Red za čekanje možemo da zamislimo kao jednu dugačku
i usku cev u koju ubacujemo elemente na jedan kraj, a vadimo ih sa drugog kraja.
Zato se red za čekanje često opisuje i kao FIFO struktura podataka (FIFO = First
In, First Out). Na Sl. 2.2 (c) je pokazano kako se red za čekanje koristi da se dobije
BFS-redosled obilaska čvorova grafa.
Za potrebe demonstracije BFS algoritma koristićemo standardnu Javinu klasu
Queue, kao i niz bft (= breadth-first time) u kome, slično DFS algoritmu, pam-
22 GLAVA 2. POVEZANOST I RASTOJANJE

2 3 4 5

6 7 8 9 10 11 12 13 14 15

(a)

2 3 4 5

6 7 8 9 10 11 12 13 14 15

(b)

Red za čekanje

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

(c)

Slika 2.2: (a) Graf G; (b) Redosled obilaska čvorova grafa G BFS algoritmom;
(c) Redosled čvorova u redu za čekanje BFS algoritma
2.2. RASTOJANJE I BFS 23

timo kojim redom smo posetili koji čvor: bft .stamp[v] == k ako i samo ako smo u
trenutku T = k posetili čvor v.
Procedura BFS koja obilazi čvorove grafa G počev od čvora v izgleda ovako:

// metod klase Graf; poziva se ovako: G.BFS(v, bft);


public void BFS(int v, TimeStamps bft) {
Queue<Integer> Q = new LinkedList<Integer>();
bft .N++;
bft .stamp[v] = bft .N;
Q.add(v);
while(Q.peek() != null){
v = Q.remove();
SkupSuseda S = susedi(v);
while(imaJos(S)){
int w = sledeci(S);
if ( bft .stamp[w] == 0){
bft .N++;
bft .stamp[w] = bft .N;
Q.add(w);
}
}
}
}

Iako na različite načine obilaze čvorove grafa, algoritme BFS i DFS ravno-
pravno možemo da koristimo da bismo utvrdili da li je graf povezan ili ne, kao i
da bismo utvrdili broj njegovih komponenti povezanosti. Analogno Posledici 2.7
imamo sledeće tvrdenje

Teorema 2.9 Neka je G graf, neka je v ∈ V (G) proizvoljno i neka je nad G izvršena
procedura BFS(v, bft) . Graf G je povezan ako i samo ako je bft .stamp[x] != 0 za
sve x ∈ V (G).

Za razliku od BFS algoritma kod koga moramo eksplicitno da koristimo red za


čekanje, DFS ima elegantnu rekurzivnu implementaciju koja se lako pamti. Zato
je DFS postao popularan, i najveći broj grafovskih algoritama se dobija nekom
modifikacijom algoritma DFS. Medutim, BFS algoritam je značajan zato što se
njegovom jednostavnom modifikacijom dobija algoritam koji efikasno odreduje
rastojanja čvorova u grafu.
24 GLAVA 2. POVEZANOST I RASTOJANJE

Rastojanje dG (x, y) čvorova x i y povezanog grafa G definišemo kao dužinu


najkraćeg puta koji ih spaja:

dG (x, x) = 0,
dG (x, y) = min{k : postoji put dužine k koji spaja x sa y}, za x 6= y.

Ako se graf G podrazumeva, umesto dG (x, y) pišemo samo d(x, y). Ovako defini-
sano rastojanje pokorava se zakonima koji odreduju da li neka funkcija zaslužuje
da se tako zove:

Teorema 2.10 Neka je G = (V, E) povezan graf. Tada je (V, dG ) metrički prostor.
Drugim rečima, za sve x, y, z ∈ V zadovoljeno je sledeće:
(D1) dG (x, y) > 0;
(D2) dG (x, y) = 0 ako i samo ako x = y;
(D3) dG (x, y) = dG (y, x); i
(D4) dG (x, z) 6 dG (x, y) + dG (y, z).
Primetimo da su čvorovi u i v susedni u povezanom grafu G ako i samo ako je
dG (u, v) = 1.
Kada primenimo BFS algoritam na povezani graf G počev od čvora v dobijamo
situaciju koja je ilustrovana na Sl. 2.3 (a). Vidimo da je skup čvorova grafa G
razbijen na slojeve L0 (v), L1 (v), L2 (v), . . . koje formalno možemo opisati ovako:

L0 (v) = {v}
Lk+1 (v) = {x ∈ V (G) : x ∈
/ L0 (v) ∪ L1 (v) ∪ . . . ∪ Lk (v) i
x je susedan sa nekim čvorom iz skupa Lk (v)}.

Teorema 2.11 Neka je G povezan graf, neka je v ∈ V (G) proizvoljno i neka su


L0 (v), L1 (v), . . . odgovarajući slojevi grafa G. Tada, za svako x ∈ V (G) važi
sledeće: x ∈ Lk (v) ako i samo ako je dG (v, x) = k.
Dokaz. Dokaz provodimo indukcijom po k. Za k = 0 i k = 1 tvrdenje je očigledno
tačno zato što je L0 (v) = {v}, dok je L1 (v) skup svih suseda čvora v, što je tačno
skup svih čvorova koji su na rastojanju 1 od v. Pretpostavimo da je tvrdenje tačno
za sve vrednosti 6 k i dokažimo da je tačno i za k + 1.
(⇒) Neka je x ∈ Lk+1 (v). Tada x ∈ / L0 (v) ∪ L1 (v) ∪ . . . ∪ Lk (v) odakle sledi
da dG (v, x) > k + 1. Prema definiciji sloja Lk+1 (v), postoji čvor y ∈ Lk (v) koji je
susedan sa x. Neka je e∗ = {x, y} grana koja ih spaja. Induktivna hipoteza nam
daje da je dG (v, y) = k, pa postoji put v e1 w1 . . . wk−1 ek y dužine k. Jasno je
da je rastojanje čvora v do svakog od čvorova wi manje od k pa prema induktivnoj
2.2. RASTOJANJE I BFS 25

L0 (v) : 1

L1 (v) : 2 3 4 5

L2 (v) : 6 7 8 9 10 11 12 13 14 15

(a)

Red za čekanje

0 1 1 1 1 2 2 2 2 2 2 2 2 2 2

(b)

Slika 2.3: (a) Slojevi koji nastaju tokom rada BFS algoritma; (b) Formiranje vred-
nosti u nizu BFT

hipotezi dobijamo da je v, w1 , . . . , wk−1 ∈ L0 (v)∪ L1 (v)∪ . . . ∪ Lk (v). Odatle sledi da


je v e1 w1 . . . wk−1 ek y e∗ x put dužine k + 1 koji spaja v sa x, pa je dG (v, x) 6 k + 1.
Dakle, dG (v, x) = k + 1.
(⇐) Neka je dG (v, x) = k + 1. Neka je v e1 w1 . . . ek wk ek+1 x put dužine k + 1
koji spaja v i x. To je najkraći put koji spaja v sa x, i zato je v e1 w1 . . . ek wk
najkraći put koji spaja v sa wk . Odatle sledi da je dG (v, wk ) = k, pa je wk ∈ Lk (v)
prema induktivnoj hipotezi. Osim toga, prema induktivnoj hipotezi x ∈ / L0 (v) ∪
L1 (v) ∪ . . . ∪ Lk (v). Dakle x ∈ Lk+1 (v), jer ne pripada nijednom sloju sa manjim
indeksom, a susedan je sa wk ∈ Lk (v). 

Prema tome, da bismo odredili rastojanje čvora v do svakog drugog čvora u


grafu dovoljno je ostale čvorove grafa razvrstati prema slojevima kojima pripadaju.
To se lako može postići modifikacijom osnovnog BFS algoritma. Ovaj put ele-
mente niza bft .stamp inicijalizujemo na −1, jer ćemo čvoru v od koga počinjemo
obilazak dodeliti vrednost 0 (on se, po definiciji, nalazi na nultom nivou). Osim
toga, ako je čvoru v dodeljena vrednost k, njegovim susedima koje do sada nismo
posetili ćemo dodeliti vrednost k + 1 (videti Sl. 2.3 (b)). Tako dobijamo metod
rastojanjaOd koji za dati čvor v vraća niz s celih brojeva sa sledećom osobinom:
s[x] = k ako i samo ako x ∈ Lk (v). Drugim rečima, s[ x ] == dG (v, x).
26 GLAVA 2. POVEZANOST I RASTOJANJE

// metod klase Graf; poziva se ovako: d = G.rastojanjaOd(v);


public int [] rastojanjaOd(int v) {
TimeStamps bft = new TimeStamps(N, −1);
Queue<Integer> Q = new LinkedList<Integer>();

bft .stamp[v] = 0;
Q.add(v);
while(Q.peek() != null){
v = Q.remove();
SkupSuseda S = susedi(v);
while(imaJos(S)){
int w = sledeci(S);
if ( bft .stamp[w] == −1){
bft .stamp[w] = bft .stamp[v] + 1;
Q.add(w);
}
}
}
return bft .stamp;
}

Zadaci za vežbu
2.1. Dokazati da za svaki paran broj n > 6 postoji povezan regularan graf ste-
pena 3 sa n čvorova koji ne sadrži C3 kao podgraf.
1
2.2. Ako je δ (G) > n(G) onda je G povezan. Dokazati.
2
2.3. Neka je G = (V, E) povezan graf sa nčvorova
 i neka je u proizvoljan čvor
n
grafa G. Dokazati da je ∑ d(u, x) 6 .
x∈V 2
2.4. Napisati program koji razvrstava čvorove grafa prema komponentama po-
vezanosti kojima pripadaju.
2.5. Napisati nerekurzivni metod DFS.
(Uputstvo: Slično kao BFS, samo što se umesto reda za čekanje koristi
stek. Stek (engl. stack) je način linearne organizacije podataka kod koga
elemente niza ne možemo da upisujemo gde želimo već možemo da ih
ZADACI ZA VEŽBU 27

dodajemo samo na kraj niza, i da ih skidamo samo s kraja niza. Stek


možemo da zamislimo kao jednu dugačku i usku čarapu u koju ubacujemo
podatke (prvi skroz na dno, drugi na njega, treći na drugi itd), a kada ih
vadimo iz čarape prvo moramo da izvadimo onaj koji je poslednji ubačen
zato što on prekriva ostale. Zato se stek često opisuje i kao LIFO struktura
podataka (LIFO = Last In, First Out). )
2.6. Modifikovati metod rastojanjaOd tako da se dobije algoritam koji odreduje
rastojanje od datog čvora v do datog čvora w. (Drugim rečima, napisati
proceduru koja kreće sa BFS algoritmom od čvora v i zaustavlja se čim se
čvoru w dodeli rastojanje.)
2.7. Pravougaona tabela formata M × N, 5 6 M, N 6 70, popunjena je nulama i
jedinicama. Odrediti na koliko delova se raspada tabela ako se iz nje iseku
sva polja označena nulama. (Dva polja se “drže” ako imaju zajedničku
ivicu; dva polja ne mogu da se drže samo o jednom temenu.)
2.8. Hiperkocka dimenzije k je graf Qk = (Vk , Ek ), gde je Vk skup svih 01-reči
dužine k, i reči a1 . . . ak , b1 . . . bk ∈ Vk su susedne u grafu ako i samo ako se
razlikuju na tačno jednom mestu. Na primer, 0101 i 0001 su susedi u Q4 ,
dok 0101 i 0000 nisu.
(a) Odrediti broj čvorova i broj grana grafa Qk .
(b) Dokazati da je Qk povezan i odrediti d(Qk ).
28 GLAVA 2. POVEZANOST I RASTOJANJE
Glava 3

Mostovi, artikulacioni čvorovi i


stabla

Ako graf predstavlja neki sistem veza, onda je važno znati gde su slabe tačke
tog sistema da bi se u realnom životu mogle dodatno obezbediti. Ovde pod slabom
tačkom podrazumevamo čvor ili granu čijim udaljavanjem se graf raspada. Tako
dolazimo do pojma mosta i artikulacionog čvora, kojima se bavi prvi odeljak ove
glave.
Razmatranje ekstremnih konfiguracija u odnosu na datu osobinu često može da
pruži dodatni uvid o toj osobini. Ako fiksiramo skup čvorova, maksimalan pove-
zan graf sa datim skupom čvorova je kompletan graf, a ta klasa grafova nije previše
interesantna. Medutim, minimalni povezani grafovi sa datim skupom čvorova su
posebno interesantni. Takve grafove zovemo stabla (iako ćemo za zvaničnu defi-
niciju odabrati nešto drugačiji pristup) i njima se bavi drugi podeljak ove glave.
Potom uvodimo pojam stabla pretraživanja grafa i stabla pretraživanja DFS algo-
ritma. Klasifikacija grana grafa u odnosu na stablo pretraživanja DFS algoritma
nam daje nekoliko elegantnih algoritama, medu kojima izdvajamo algoritam koji
odreduje sve artikulacione čvorove grafa.

3.1 Mostovi i artikulacioni čvorovi


Neka je e grana, a v čvor grafa G. Sa G − e označavamo graf koji se dobija od
grafa G udaljavanjem grane e, dok sa G − v označavamo graf koji se dobija od grafa
G udaljavanjem čvora v i svih grana grafa G koje su incidentne sa v. Artikulacioni
čvor grafa G je čvor v ∈ V (G) sa osobinom cc(G − v) > cc(G). Most grafa G je
grana e ∈ E(G) sa osobinom cc(G − e) > cc(G). Artikulacioni čvorovi i mostovi
su “slabe tačke” grafa jer se njihovim udaljavanjem graf raspada. Intuitivno, arti-

29
30 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

kulacioni čvor i most u grafu izgledaju ovako:


A B A B
e
v

most artikulacioni čvor

Teorema 3.1 Neka je e grana grafa G. Tada, e je most grafa G ako i samo ako e
ne pripada nijednoj konturi grafa G.
Dokaz. Dokaz provodimo za povezane grafove. Ako G nije povezan, dovoljno je
ograničiti se na komponentu povezanosti koja sadrži e.
(⇒): Pretpostavimo da grana e pripada konturi C = v0 e v1 e2 v2 . . . vk−1 ek v0

grafa G. Da bismo pokazali da je G − e povezan uzmimo proizvoljne čvorove
x 6= y. Zato što je G povezan, postoji put P koji spaja x sa y. Ako P ne sadrži
granu e, to je onda i put u G − e koji spaja x sa y. Ako, medutim, P sadrži granu e,
recimo P = x . . . v0 e v1 . . . y, tada možemo pojavljivanje grane e na putu P zameniti
sa C − e i tako dobiti šetnju W = x . . . v0 ek vk−1 . . . v2 e2 v1 . . . y, Sl. 3.1. Zato što
| {z }
C−e
se e pojavljuje samo jednom u P i samo jednom u C, sledi da se e ne pojavljuje u
šetnji W , tako da je W šetnja koja spaja x sa y u G − e.
x v0 e v1 y
P
ek e2
vk−1 C v2

Slika 3.1: Šetnja W

(⇐) Pretpostavnimo, sada, da grana e nije most grafa G i neka je e = {x, y}.
Tada je graf G − e povezan, pa postoji put x e1 v1 e2 . . . vk−1 ek y koji u G − e
spaja x sa y. Zato što je ovo put u G − e, svi čvorovi x, v1 , . . . , vk−1 , y su različiti i
e∈/ {e1 , e2 , . . . , ek }. Dakle, x e1 v1 e2 . . . vk−1 ek y e x je kontura u G koja sadrži e. 
Teorema 3.2 Čvor v je artikulacioni čvor grafa G ako i samo ako se čvorovi skupa
V (G) \ {v} mogu podeliti u dve neprazne grupe A i B tako da za svako a ∈ A i
svako b ∈ B, svaki put od a do b sadrži v.
Dokaz. Dokaz provodimo za povezane grafove. Ako G nije povezan, dovoljno je
ograničiti se na komponentu povezanosti koja sadrži v.
3.2. DETEKCIJA ARTIKULACIONIH ČVOROVA I MOSTOVA 31

(⇒) Neka je v artikulacioni čvor grafa G. Tada G − v nije povezan graf. Neka
su S1 , S2 , . . . , Sk komponente povezanosti grafa G − v i neka je A = S1 i B =
S2 ∪ . . . ∪ Sk . Neka su a ∈ A i b ∈ B proizvoljni. Neka je j > 2 takvo da je b ∈ S j .
Ako bi u grafu G postojao put od a do b koji ne sadrži v, to bi onda bio i put od a
do b u grafu G − v, pa bi sledilo da u grafu G − v postoji put od komponente S1 do
komponente S j . No, tada S1 i S j ne bi bile različite komponente povezanosti grafa
G − v, što je nemoguće. Dakle, svaki put od a do b u G sadrži v.
(⇐) Pretpostavimo da smo čvorove skupa V (G) \ {v} podelili u dve neprazne
grupe tako da za svako a ∈ A i svako b ∈ B, svaki put od a do b sadrži v. Odaberimo
proizvoljno a ∈ A i proizvoljno b ∈ B. Kako u grafu G svaki put od a do b sadrži
v, sledi da u grafu G − v ne postoji put od a do b. Dakle, graf G − v nije povezan i
zato je v artikulacioni čvor. 

Lako se pokazuje da je cc(G − e) = cc(G) + 1 za svaki most e grafa G. Ako


je v artikulacioni čvor grafa G onda je cc(G − v) < cc(G) + δ (v), i to najbolje što
možemo da zaključimo bez dodatnih pretpostavki o grafu G.

3.2 Detekcija artikulacionih čvorova i mostova


Prema Teoremi 3.2, čvor v je artikulacioni čvor v
grafa G ako i samo ako se čvorovi skupa V (G)\{v} x y
mogu podeliti u dve neprazne grupe A i B tako da
za svako a ∈ A i svako b ∈ B, svaki put od a do b B
sadrži v. Tako dobijamo jednostavan algoritam koji A
proverava da li je čvor v artikulacioni čvor grafa G:

(1) Označimo čvor v kao posećen


(2) Pustimo DFS od nekog suseda x čvora v
(3a) Ako su nakon DFS svi susedi čvora v posećeni, v nije artikulacioni čvor.
(3b) Ako, medutim, postoji sused y čvora v koji nije posećen, to znači da se
od x do y ne može doći drugim putem osim preko čvora v; zato x i y
pripadaju različitim delovima podele (A, B), pa je v artikulacioni čvor.
Algoritam koga smo upravo opisali radi pod pretpostavkom da v nije izolovani
čvor (odnosno, zahteva se da v ima bar jednog suseda). Ukoliko je v izolovani čvor
on po definiciji ne može biti artikulacioni čvor.
32 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

public boolean artCv(int v) {


if (deg(v) == 0 || deg(v) == 1) return false;
TimeStamps dft = new TimeStamps(N, 0);
dft .stamp[v] = 1;
SkupSuseda S = susedi(v);
int x = sledeci(S);
DFS(x, dft );
do {
x = sledeci(S);
if ( dft .stamp[x] == 0) return true;
} while(imaJos(S));
return false;
}

Veoma lako se može proveriti da li je grana e = {u, v} most: udaljimo granu


iz grafa i pustimo DFS od čvora u. Ako algoritam poseti čvor v, grana e nije most
pošto postoji “okolni” put od u do v. U suprotnom grana e jeste most grafa G.

public boolean most(int u, int v) {


ukloniGranu(u, v);
TimeStamps dft = new TimeStamps(N, 0);
DFS(u, dft );
boolean jeste = dft .stamp[v] == 0;
dodajGranu(u, v);
return jeste ;
}

3.3 Stabla
Stablo je povezan graf koji ne sadrži konture. Prema Teoremi 3.1 svaka grana
stabla je most. Stablo je minimalan povezan graf sa datim skupom čvorova. Na-
redna teorema pokazuje da stabla na izvestan način opisuju esenciju pojma pove-
zanosti. Podsetimo se da je graf H = (W, E ′ ) pokrivajući podgraf grafa G = (V, E)
ako je W = V i E ′ ⊆ E. Ako je uz to H još i stablo, kažemo da je H pokrivajuće
stablo grafa G.
3.3. STABLA 33

Ako pažljivo pogledamo DFS algoritam d b a


kada radi na povezanom grafu vidimo da se
tokom njegovog rada konstruiše jedno spe- b c
cijalno pokrivajuće stablo polaznog grafa. e a
Svaka grana stabla vodi od čvora koga tre- d f
nutno razmatramo ka čvoru koga još nismo
f c
obišli. Osim toga, u stablu pretraživanja je g
e
istaknut jedan čvor – čvor od koga smo kre-
nuli sa obilaskom. Za taj čvor kažemo da je g
koren stabla.
Stablo pretraživanja ili korensko stablo je uredeni par (T, v) gde je T stablo, a
v njegov proizvoljan čvor. Čvor v zovemo koren stabla pretraživanja (T, v). Stablo
pretraživanja (T, v) je stablo pretraživanja u grafu G ako je T pokrivajuće stablo
grafa G.
Kažemo da je čvor x otac čvora y
predak v T
i da je čvor y sin čvora x ako je {x, y}
grana stabla pretraživanja (T, v) i ako je
dT (v, x) < dT (v, y), tj. ako je x bliži ko- u otac
renu stabla nego y. Slično, kažemo da je potomak
čvor u predak čvora w i da je čvor w po- x sin
tomak čvora u ako postoji niz čvorova x1 ,
x2 , . . . xk , k > 2, takav da je x1 = u, xk = w w y
i svaki xi je otac od xi+1 . Drugim rečima,
u je predak od w ako jedinstveni put od v
do w kroz T prolazi kroz u.
Stablo pretraživanja algoritma DFS je stablo pretraživanja koje nastaje radom
algoritma DFS nad povezanim grafom. Koren stabla je čvor od koga startuje al-
goritam. Grana {x, y} je grana stabla pretraživanja algoritma ako i samo ako se
prilikom izvršavanja procedure DFS(x, dft) u telu while-ciklusa realizuje rekur-
zivni poziv DFS(y, dft) . (Analogno se može uvesti i pojam stabla pretraživanja
algoritma BFS, ali se njegovim svojstvima nećemo detaljno baviti.)
Neka je (T, v) stablo pretraživanja a
povezanog grafa G. Za granu e =
{x, y} kažemo da je povratna grana b c
ako to nije grana stabla T , ali je je-
dan od čvorova x, y predak onog dru- grane stabla
d f
gog. Grane iz skupa E(G) \ E(T ) povratne grane
koje nisu povratne grane zovu se po- e g poprečne grane
prečne grane.
34 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

Prema tome, svako stablo pretraživanja u povezanom grafu klasifikuje grane


grafa na:

• grane stabla,
• povratne grane, i
• poprečne grane.

Kada se stablo pretraživanja crta od gore ka dole povratne grane (engl. backed-
ges) vode “u natrag” i odatle ime. Naravno, ako je (T, v) proizvoljno stablo pre-
traživanja grafa, u tom grafu mogu da postoje sve tri vrste grana. Medutim, stablo
pretraživanja DFS algoritma je posebno:

Teorema 3.3 U stablu pretraživanja DFS algoritma nad povezanim grafom nema
poprečnih grana.

Dokaz. Pretpostavimo da to nije tačno i neka je e = {x, y} u


poprečna grana u stablu pretraživanja (T, v) DFS algoritma
nad povezanim grafom G. Neka je u najbliži zajednički pre- p q
dak čvorova x i y u stablu T , neka je p sin čvora u koji je
predak od x, i neka je q sin čvora u koji je predak od y. Pro- x
cedura DFS(u, dft) će u jednom trenutku pozvati DFS(p, dft), e
a nakon toga DFS(q, dft). Kako se čvor y nalazi u nizu re- y
kurzivnih poziva koji kreće od poziva DFS(q, dft), sledi da
je nakon završetka procedure DFS(p, dft) važilo dft .stamp[y] = 0. S druge strane,
niz rekurzivnih poziva koji kreće sa DFS(p, dft) će u jednom trenutku stići i do
čvora x, a nakon izvršenja procedure DFS(x, dft) svi susedi čvora x imaju time-
stamp različit od nule. Dakle, nakon poziva DFS(x, dft) , a pre poziva DFS(q, dft)
će važiti dft .stamp[y] != 0. Kontradikcija. 
Ovo tvrdenje sada možemo da iskoristimo za dobijanje efikasnog kriterijuma
za proveru da li je dati povezan graf stablo, kako pokazuje sledeća teorema:

Teorema 3.4 Povezan graf je stablo ako i samo ako stablo pretraživanja DFS al-
goritma nad tim grafom nema povratnu granu.

Dokaz. Neka je (T, v) stablo pretraživanja DFS algoritma nad povezanim gra-
fom G.
(⇐) Ako stablo T ima povratnu granu e = {x, y}, grana e sa putem od x do y
kroz stablo T zatvara konturu, pa polazni graf nije stablo.
(⇒) Pretpostavimo sada da stablo T nema povratnih grana. Kako stablo pre-
traživanja DFS algoritma nema poprečnih grana (Teorema 3.3), sledi da je E(G) =
3.3. STABLA 35

E(T ). S druge strane, V (G) = V (T ) jer je T pokrivajuće stablo grafa G. Dakle,


G = T i zato je G stablo. 

Imaćemo situacije kada znamo da graf koga posmatramo nije povezan, ali nas
interesuje da li je komponenta povezanosti kojoj pripada dati čvor x stablo. U tom
slučaju dovoljno je pustiti DFS od čvora x i proveriti da li se pojavila povratna
grana. Proceduri DFS se ovaj put mora proslediti ne samo čvor od koga počinjemo
već i redni broj njegovog oca u stablu pretraživanja da bismo mogli da identifi-
kujemo povratne grane: grana je povratna ako ide od tekućeg čvora ka nekom
označenom čvoru koji nije otac tekućeg čvora.
private boolean imaPovratnuGr(int v, int otac, TimeStamps dft) {
boolean povratnaGr = false;
dft .stamp[v] = 1;
SkupSuseda S = susedi(v);
while(!povratnaGr && imaJos(S)){
int w = sledeci(S);
if ( dft .stamp[w] == 0){
povratnaGr = imaPovratnuGr(w, v, dft);
}
else if (w != otac) {
povratnaGr = true;
}
}
return povratnaGr;
}

public boolean kompJeStablo(int v) {


TimeStamps dft = new TimeStamps(N, 0);
return !imaPovratnuGr(v, NoVertex, dft);
}
36 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

3.4 Kombinatorna svojstva stabala


Analizom rada DFs algoritma iz prethodnog odeljka lako dolazimo do sledećeg
važnog svojstva stabala.

Teorema 3.5 Graf je povezan ako i samo ako ima pokrivajuće stablo.
Dokaz. Ako graf ima pokrivajući podgraf koji je povezan, onda i polazni graf
mora biti povezan. Dakle, ako graf ima pokrivajuće stablo, on je povezan. Obr-
nuto, ako je graf povezan onda DFS algoritam poseti svaki čvor tog grafa. Stablo
pretraživanja DFS algoritma je pokrivajuće stablo grafa. 

Lema 3.6 Stablo sa bar dva čvora ima bar dva viseća čvora.
Dokaz. Neka je G stablo sa n > 2 čvorova i neka je v1 v2 . . . vk najduži put u stablu.
Tada je k > 2 jer je G povezan graf sa bar dva čvora. Ako je δ (v1 ) > 1 onda v1
ima suseda x koji nije v2 . Ako bi x bio novi čvor, tj. x ∈ / {v3 , . . . , vk }, tada bi put
x v1 v2 . . . vk bio duži od najdužeg puta u G, što nije moguće. S druge strane, ako je
x ∈ {v3 , . . . , vk } onda G ima konturu, što je u suprotnosti sa pretpostavkom da je G
stablo. Dakle, v1 je viseći čvor. Na isti način pokazujemo da je i vk viseći čvor. 

Teorema 3.7 Neka je G = (V, E) stablo sa n čvorova i m grana. Tada je m = n − 1,


i shodno tome ∑ δ (v) = 2(n − 1).
v∈V

Dokaz. Drugi deo tvrdenja je direktna posledica Prve teoreme teorije grafova.
Dokažimo sada da je m = n − 1. Dokaz provodimo indukcijom po n. Slučajevi
n = 1 i n = 2 su trivijalni. Pretpostavimo da je tvrdenje tačno za sva stabla sa ma-
nje od n čvorova i posmatrajmo stablo G sa n čvorova. Prema Lemi 3.6 stablo G
ima viseći čvor x. Prema Teoremi 3.2 stepen artikulacionog čvora je najmanje 2.
Zato x nije artikulacioni čvor grafa G, pa je G − x povezan. Jasno je i to da G − x
nema konture (uklanjanje čvorova ne može da dovede do toga da se u grafu pojave
konture), odakle sledi da je G − x stablo sa manje od n čvorova. Prema induktivnoj
hipotezi, m′ = n′ − 1, gde je m′ = m(G − x) i n′ = n(G − x). Kako je m′ = m − 1 i
n′ = n − 1 (x je viseći čvor), zaključujemo da je m = n − 1. 

Teorema 3.8 Neka je G graf sa n čvorova i m grana. Ako je m = n − 1 i ako G


nema konture onda je G povezan (i stoga stablo).
Dokaz. Neka je m = n − 1, neka G nema konture i neka su S1 , . . . , Sk komponente
povezanosti grafa G. Svaka komponenta je stablo, pa je mi = ni − 1 za sve i, gde je
k k k
mi = m(Si ) i ni = n(Si ). Odatle je ∑ mi = ∑ ni − k tj. m = n − k (jer je m = ∑ mi
i=1 i=1 i=1
3.4. KOMBINATORNA SVOJSTVA STABALA 37

k
i n = ∑ ni ). Iz pretpostavke m = n − 1 sada lako zaključujemo da je k = 1, tj. G je
i=1
povezan graf. 

Teorema 3.9 Neka je G povezan graf sa n > 2 čvorova i m grana i neka je


m = n − 1. Tada G nema konture (i stoga je G stablo).
Dokaz. Prema Teoremi 3.5 graf G = (V, E) ima pokrivajuće stablo H = (V, E ′ ).
Zato što je H stablo, Teorema 3.7 nam daje m(H) = n(H)− 1 = n− 1. Pretpostavka
m = n− 1 sada implicira m(H) = m pa iz E ′ ⊆ E zaključujemo da je E ′ = E. Dakle,
G = H i tako je G stablo. 

Posledica 3.10 Svake dve od naredne tri osobine impliciraju onu treću:

• graf je povezan,
• graf nema konture,
• m = n − 1.

Posebno, povezan graf sa n čvorova i m grana je stablo ako i samo ako je m = n− 1.


Sada možemo veoma lako da proverimo da li je graf stablo:

public boolean stablo() {


return povezan() && M == N − 1;
}

Odeljak o stablima ćemo zaključiti značajnim rezultatom o broju različitih sta-


bala na datom skupu čvorova. Važno je napomenuti da kada brojimo strukture
možemo brojati različite strukture, ili neizomorfne strukture. Na primer, postoji
16 različitih stabala na skupu od četiri elementa, a samo dva neizomorfna, kako
je to pokazano na Sl. 3.2. Ne treba da nas iznenadi to što je brojanje neizomorf-
nih struktura daleko komplikovanije od brojanja različitih struktura. Sada ćemo
dokazati teoremu Cayleya o broju različitih stabala na datom skupu čvorova sa n
elemenata. Pokazaćemo dokaz koga je dao H. Prüfer 1918. godine.1

1 H.Prüfer, Neuer Beweis eines Satzes über Permutationen, Archiv der Math. und Phys. (3)
27(1918), 142–144.
38 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

1 2 1 2 1 2 1 2

3 4 3 4 3 4 3 4
1 2 1 2 1 2 1 2

3 4 3 4 3 4 3 4
1 2 1 2 1 2 1 2

3 4 3 4 3 4 3 4
1 2 1 2 1 2 1 2

3 4 3 4 3 4 3 4

Slika 3.2: Šesnaest različitih i samo dva neizomorfna stabla na skupu od četiri
čvora

Teorema 3.11 (Cayley 1889) Broj različitih stabala sa n čvorova je nn−2 .


Dokaz. Neka je V = {1, . . . , n} konačan skup koji ćemo koristiti kao skup čvorova.
Ideja dokaza se zasniva na principu bijekcije. Pokazaćemo kako se svako stablo sa
skupom čvorova V može može jednoznačno kodirati nizom (a1 , . . . , an−2 ) eleme-
nata skupa V , i kako se od svakog niza (a1 , . . . , an−2 ) može rekonstruisati stablo
čiji je to kod.
Prvo ćemo pokazati kako se konstruiše Prüferov kod stabla. Neka je T stablo
sa skupom čvorova V . Konstruisaćemo niz stabala (Ti )16i6n−2 i dva niza celih
brojeva, Prüferov kod (ai )16i6n−2 i pomoćni niz (bi )16i6n−2 . Neka je T1 = T . Ako
nam je dato stablo Ti , neka je bi najmanji viseći čvor stabla Ti (čvorovi stabla su
celi brojevi, pa od svih brojeva koji se javljaju kao viseći čvorovi stabla odaberemo
najmanji) i neka je ai njegov jedini sused. Sada stavimo Ti+1 = Ti − bi i ponovimo
postupak dok ne dobijemo stablo sa samo dva čvora. Prüferov kod polaznog stabla
je (a1 , a2 , . . . , an−2 ). Primer konstrukcije koda dat je na Sl. 3.3. Tako smo dobili
funkciju ϕ : Tn → {1, . . . , n}n−2 koja svakom stablu dodeljuje njegov Prüferov kod.
Obrnuto, ako nam je dat neki niz (a1 , . . . , an−2 ) celih brojeva iz skupa V odgo-
varajuće stablo konstruišemo na sledeći način. Za S ⊆ {1, . . . , n} neka je sa
mix S = min({1, . . . , n} \ S)
označen najmanji broj koji nije u S (minimal excluded). Stavimo an−1 = n i kon-
struišemo b1 , b2 , . . . , bn−1 ovako:
bi = mix{ai , . . . , an−1 , b1 , . . . , bi−1 }
3.4. KOMBINATORNA SVOJSTVA STABALA 39

(za i = 1 u skupu nema nijednog elementa b j , naravno). Na primer, u slučaju niza


(4, 7, 3, 4, 1, 4, 4) imamo da je a8 = 9 i

b1 = mix{4, 7, 3, 4, 1, 4, 4, 9} = 2
b2 = mix{ 7, 3, 4, 1, 4, 4, 9, 2} = 5
b3 = mix{ 3, 4, 1, 4, 4, 9, 2, 5} = 6
b4 = mix{ 4, 1, 4, 4, 9, 2, 5, 6} = 3
b5 = mix{ 1, 4, 4, 9, 2, 5, 6, 3} = 7
b6 = mix{ 4, 4, 9, 2, 5, 6, 3, 7} = 1
b7 = mix{ 4, 9, 2, 5, 6, 3, 7, 1} = 8
b8 = mix{ 9, 2, 5, 6, 3, 7, 1, 8} = 4

Ovaj proces se zove procedura rekonstrukcije. Skup {{bi , ai } : 1 6 i 6 n} je skup


grana stabla čiji Prüferov kod je (a1 , . . . , an−2 ), ali to ovom prilikom nećemo doka-
zivati. 

5 7 1 4 9 7 1 4 9 4 9
2
6 3 8 3 8 8
bi : 2 bi : 2 5 6 3 bi : 2 5 6 3 7 1 8
ai : 4 ai : 4 7 3 7 ai : 4 7 3 7 1 4 4
5 7 1 4 9 7 1 4 9 4 9
STOP
6 3 8 8
bi : 2 5 bi : 2 5 6 3 7
ai : 4 7 ai : 4 7 3 7 1
7 1 4 9 1 4 9
5 7 1 4 9
6 3 8 8
2
6 3 8
bi : 2 5 6 bi : 2 5 6 3 7 1
ai : 4 7 3 ai : 4 7 3 7 1 4 4 7 3 7 1 4 4

Slika 3.3: Prüferov kod stabla


40 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

3.5 Bipartitni grafovi


Skup čvorova W ⊆ V (G) je nezavisan ako je E(G[W ]) = ∅, tj. medu čvorovima
iz W ne postoje dva koji su susedni u G. Ako su A, B ⊆ V (G) disjunktni, sa E(A, B)
označavamo skup svih grana čiji jedan kraj je u A, a drugi u B.
Graf G je bipartitan ako postoji particija {X ,Y } skupa V (G) takva da svaka
grana grafa G ima jedan kraj u X , a drugi u Y . Drugim rečima, E(G) = E(X ,Y ),
odakle sledi da su X i Y nezavisni skupovi. Kompletan bipartitan graf je bipartitan
graf sa particijom čvorova {X ,Y } čiji skup grana čine svi neuredeni parovi {x, y}
za koje je x ∈ X i y ∈ Y . Ako je |X | = p i |Y | = q, kompletan bipartitan graf
sa particijom skupa čvorova {X ,Y } označavamo sa K p,q . Zvezda sa n čvorova, u
oznaci Sn , je kompletan bipartitan graf K1,n−1 . Jedan bipartitan graf, graf K3,4 i
zvezda S10 prikazani su na Sl. 3.4.

Y
K3,4 S10

Slika 3.4: Jedan bipartitan graf, graf K3,4 i zvezda S10

Sada ćemo dati važnu karakterizaciju bipartitnih grafova. Krenimo od jednog


pomoćnog rezultata.

Lema 3.12 Svaka zatvorena šetnja neparne dužine sadrži neparnu konturu.

Dokaz. Dokaz provodimo po indukcijom po dužini šetnje. Svaka zatvorena šetnja


dužine 3 je zapravo kontura C3 i tvrdenje je tačno. Pretpostavimo da je tvdenje
tačno za sve zatvorene neparne šetnje dužine strogo manje k i posmatrajmo proi-
zvoljnu zatvorenu neparnu šetnju dužine k:

v0 e1 v1 e2 v2 . . . vk−1 ek vk = v0 .

Ako su svi čvorovi iz skupa {v0 , v1 , . . . , vk−1 } različiti, ova zatvorena šetnja je ne-
parna kontura i tvrdenje je pokazano. Pretpostavimo, zato, da je vi = v j za neke
i, j ∈ {0, 1, . . . , k − 1}, i < j:
3.5. BIPARTITNI GRAFOVI 41

v1
vi−1 vi+1
v0 vi
vk W1 vj W2
v j+1
vk−1 v j−1

Tada se polazna šetnja raspada na dve zatvorene šetnje:

W1 = v0 e1 v1 . . . vi e j+1 v j+1 . . . vk−1 ek vk


W2 = vi ei+1 vi+1 . . . v j−1 e j−1 v j

Jedna od njih, recimo W1 , je neparne dužine (jer ako su obe parne ili obe neparne,
polazna šetnja bi bila parne dužine), pa prema induktivnoj hipotezi, ona sadrži
neparnu konturu. Time je pokazano da i polazna zatvorena šetnja sadrži neparnu
konturu. 

Teorema 3.13 Graf sa bar dva čvora je bipartitan ako i samo ako ne sadrži neparnu
konturu.
Dokaz. Lako se vidi da je graf sa bar dva čvora bipartitan ako i samo ako je svaka
njegova komponenta povezanosti ili izolovani čvor ili bipartitan graf. Zato je do-
voljno dokazati teoremu za povezane grafove, pa pretpostavimo da je G povezan
graf i n(G) > 2.
(⇒) Neka je G bipartitan graf i pretpostavimo da G sadrži neparnu konturu čiji
čvorovi su v1 , v2 , . . . , v2k+1 . Neka su oznake uvedene tako da je vi susedan sa vi+1
za i ∈ {1, . . . , 2k}, i v2k+1 je susedan sa v1 . Neka je {X ,Y } particija skupa V (G)
koja pokazuje da je G bipartitan graf, tj. koja ima osobinu E(G[X ]) = E(G[Y ]) = ∅.
Čvor v1 pripada jednom od dva bloka particije, pa bez umanjenja opštosti možemo
pretpostaviti da je v1 ∈ X . Tada je v2 ∈ Y zato što je v2 susedan sa v1 , a G je biparti-
tan. Na isti način zaključujemo da je v3 ∈ X , v4 ∈ Y i tako dalje. Vidimo da čvorovi
sa neparnim indeksom pripadaju skupu X , odakle sledi v2k+1 ∈ X . Medutim, i
x1 ∈ X , pa E(G[X ]) sadrži granu {x1 , x2k+1 } što je u suprotnosti sa pretpostav-
kom E(G[X ]) = ∅.
(⇐) Pretpostavimo da G ne sadrži neparnu konturu i pokažimo da je to bipar-
titan graf. Uzmimo proizvoljan čvor v ∈ V (G) i definišimo A0 , A1 , . . . ⊆ V (G) na
sledeći način:
An = {x ∈ V (G) : d(v, x) = n},
za n > 0. Zato što je G povezan, postoji put koji spaja v sa svakim drugim čvorom
grafa, pa zaključujemo da se svaki čvor grafa G javlja u bar jednom od skupova Ai .
42 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

(Skupovi Ai su disjunktni po konstrukciji, a činjenica da je V (G) konačan implicira


da postoji s takvo da je {A0 , A1 , . . . , As } particija skupa V (G) i At = ∅ za sve t > s.)
Neka je [ [
X= Aj i Y = Aj
j parno j neparno

i pokažimo da su i X i Y nezavisni skupovi u G.


Pretpostavimo suprotno: postoje čvorovi x, y ∈ X takvi da su x i y susedni.
Po konstrukciji skupa X postoji put P1 parne dužine koji spaja v sa x, i postoji
put P2 parne dužine koji spaja y sa v. Nadovezivanjem ova dva puta i grane
e = {x, y} dobijamo zatvorenu šetnju v| .{z
. . x} e y . . . v koja je neparne dužine, pa
| {z }
P1 P2
prema Lemi 3.12 graf G ima neparnu konturu. Kontradikcija.
Dokaz da je skup Y nezavisan je analogan. Dakle, i X i Y su nezavisni skupovi,
čime je pokazano da je G bipartitan graf. 

Primetimo da prethodna teorema ne implicira da bipartitni grafovi moraju da


imaju konture. Graf bez kontura je bipartitan graf, i to sledi iz prethodne teoreme
zato što graf bez kontura nema neparnih kontura.
Metod kompJeBipart(int v) proverava da li je komponenta čvora v bipartitan
graf. Zato što stablo pretraživanja DFS algoritma nema poprečne grane, lako se
zaključuje sledeće:

Posledica 3.14 Povezan graf ima neparnu konturu ako i samo ako postoji povratna
grana u stablu pretraživanja DFS algoritma koja zatvara neparnu konturu.
Zato je ideja algoritma koji proverava da li je komponenta čvora v bipartitan
graf slična ideji koju smo koristili da proverimo da li je komponenta stablo. Tamo
je bilo bitno da ne postoje povratne grane, a ovde je bitmo da povratne grane,
ukoliko postoje, ne zatvore neparnu konturu. Da bismo proverili da li je kontura
parna koristićemo veoma jednostavno označavanje. Čvorove ćemo u nizu dft .stap
naizmenično označavati sa 1 ili 2 i to tako da ako je otac u stablu pretraživanja
označen sa s, onda su svi njegovi sinovi označeni sa 3 − s, s ∈ {1, 2}. Tada graf
ima neparnu konturu ako i samo ako postoji povratna grana čiji čvorovi su označeni
na isti način. Obzirom da oznake idu naizmenično 1 − 2 − 1 − 2 − . . . , kod neparne
konture se moraju pojaviti dva susedna čvora koji su označeni na isti način.
ZADACI ZA VEŽBU 43

private boolean imaNepKonturu(int v, int otac, TimeStamps dft) {


boolean nepKontura = false;
if (otac == NoVertex) {
dft .stamp[v] = 1;
}
else {
dft .stamp[v] = 3 − dft .stamp[otac];
}
SkupSuseda S = susedi(v);
while(!nepKontura && imaJos(S)){
int w = sledeci(S);
if ( dft .stamp[w] == 0){
nepKontura = imaNepKonturu(w, v, dft);
}
else if ( dft .stamp[v] == dft .stamp[otac]) {
nepKontura = true;
}
}
return nepKontura;
}

public boolean kompJeBipart(int v) {


TimeStamps dft = new TimeStamps(N, 0);
return !imaNepKonturu(v, NoVertex, dft);
}

Zadaci za vežbu
3.1. (a) Dati primer grafa koji nema ni artikulacioni čvor ni most.
(b) Dati primer grafa koji ima artikulacioni čvor, ali nema most.
(c) Dati primer grafa koji nema artikulacioni čvor, ali ima most.
(d) Dati primer grafa koji ima i artikulacioni čvor i most.
3.2. Neka je G povezan graf sa bar dva čvora. Dokazati da G ima bar dva čvora
koji nisu artikulacioni čvorovi.
3.3. Neka je stepen svakog čvora u povezanom grafu G paran. Dokazati da je
44 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA

1
cc(G − v) 6 δ (v) za sve v ∈ V (G).
2
3.4. Graf je stablo ako i samo ako za svaki par različitih čvorova postoji tačno
jedan put koji ih spaja. Dokazati.
3.5. Graf je stablo ako i samo ako ima jedinstveno pokrivajuće stablo. Doka-
zati.
3.6. Dokazati da stablo G ima bar ∆(G) visećih čvorova.
3.7. Neka je T stablo, ∆ = ∆(T ) i fk broj čvorova u T čiji stepen je k. Dokazati

da je f1 = 2 + ∑ (k − 2) fk .
k=3

3.8. Za svako n > 4 naći graf G sa n čvorova tako da za svako k ∈ {2, . . . , n− 2}


graf G ima pokrivajuće stablo dijametra k. (Dijametar grafa G je najveći
ceo broj s takav da postoje x, y ∈ V (G) sa osobinom d(x, y) = s.)
3.9. Šuma je graf čije komponente povezanosti su stabla. Dokazati da je G
šuma ako i samo ako je δ (H) 6 1 za svaki indukovani podgraf H grafa G.
3.10. Odrediti broj različitih pokrivajućih stabala grafa Kn .
†3.11. Dokazati da svako pokrivajuće stablo povezanog grafa sadrži sve mostove
tog grafa.
3.12. Dokazati da u stablu pretraživanja BFS algoritma nad povezanim grafom
nema povratnih grana.
3.13. Dokazati: Povezan graf je stablo ako i samo ako stablo pretraživanja BFS
algoritma nad tim grafom nema poprečnu granu.
†3.14. Blok povezanog grafa G je maksimalan skup čvorova S ⊆ V (G) sa osobi-
nom da G[S] nema artikulacione čvorove (drugim rečima, ako je S′ ⊇ S i
ako G[S′ ] nema artikulacione čvorove, onda je S′ = S).

(a) Dokazati da dva bloka u grafu mogu imati najviše jedan zajednički
čvor.

(b) Neka su B1 , . . . , Bk blokovi grafa G i neka je BG graf sa skupom


čvorova {1, . . . , k} kod koga je i susedan sa j ako i samo ako i 6= j i blokovi
Bi i B j imaju neprazan presek. Dokazati da je BG stablo.
3.15. Primetimo, prvo, da je svako stablo bipartitan graf, zato što stablo nema
kontura, pa ne može imati ni neparne konture. Neka je {X ,Y } particija
skupa čvorova stabla T koja pokazuje da je T bipartitan graf, i neka je
|X | = |Y | + p za neko p > 0. Dokazati da se u skupu X nalazi bar p + 1
ZADACI ZA VEŽBU 45

visećih čvorova stabla T .


3.16. Napisati program koji učitava povezan graf G, njegov artikulacioni čvor
v i bez udaljavanja čvora v iz grafa G odreduje komponente povezanosti
grafa G − v.
3.17. Napisati program koji za dati graf odreduje da li je 2-povezan. (Za graf
kažemo da je 2-povezan ako nema artikulacionih čvorova.)
46 GLAVA 3. MOSTOVI, ARTIKULACIONI ČVOROVI I STABLA
Glava 4

Težinski grafovi

Ukoliko je graf nastao apstrakcijom neke prostorne situacije, često želimo da


zapamtimo koliko je bilo rastojanje izmedu objekata koji su predstavljeni čvoro-
vima. Tada svakoj grani u grafu dodelimo neki pozitivan broj koji se zove težina
grane. Graf kod koga je svakoj grani dodeljena težina zove se težinski graf. Takvi
grafovi se javljaju recimo u problemima modeliranja transporta tereta: čvorovi
mogu da predstavljaju gradove, a brojevi pridruženi granama rastojanja izmedu
gradova ili cenu prevoza izmedu dva grada.

4.1 Uvod
Težinski graf je uredeni par (G, w) gde je 2
G graf, a w : E(G) → N funkcija koja svakoj 1 3
grani e grafa G dodeljuje pozitivan ceo broj 8
w(e) koji se zove težina grane. Funkciju w 3 6
21 9
zovemo težinska funkcija. Primer jednog te-
žinskog grafa dat je na slici pored. U tom 1
primeru težina grane {1, 3} je 21. 4 17 6 7
Stepen čvora u težinskom grafu (G, w),
povezanost težinskog grafa, podgraf težin-
skog grafa, kao i mnogi drugi pojmovi, pre- 4 12
5
nose se direktno sa grafa G.
Medutim, rastojanje u težinskom grafu ćemo definisati drugačije, na način koji
uzima u obzir težine grana. Težina podgrafa H težinskog grafa (G, w) se uvodi
prirodno:
w(H) = ∑ w(e).
e∈E(H)

47
48 GLAVA 4. TEŽINSKI GRAFOVI

Rastojanje čvorova u povezanom težinskom grafu (G, w) definišemo ovako:


(
0, x=y
d(G,w) (x, y) =
min{w(P) : P je put koji spaja x i y}, x 6= y.

Ukoliko je iz konteksta jasno o kom težinskom grafu se govori, umesto d(G,w) (x, y)
pisaćemo kratko d(x, y).

Primer 4.1 Rastojanje čvorova 4 i 6 u grafu na početku odeljka je 8 zato što je to


težina najlakšeg puta koji ih spaja. Najlakši put koji spaja 4 sa 6 je 4 − 3 − 2 − 6.
Postoje putevi sa manje grana koji spajaju 4 sa 6, ali svi oni imaju veću težinu.
Graf koji nije težinski možemo uvek da shvatimo kao težinski graf kod koga
svaka grana ima težinu 1. Na taj način pojam rastojanja u težinskom grafu postaje
prirodno uopštenje pojma rastojanja u običnom grafu. Kao i ranije, imamo sledeći
značajan rezultat:

Teorema 4.2 Neka je (G, w) težinski graf. Tada je (V (G), d(G,w) ) metrički prostor.

4.2 Reprezentacija težinskih grafova


Težinske grafove najčešće reprezentujemo koristeći težinsku matricu grafa koja
je modifikacija matrice susedstva. Neka je G težinski graf sa skupom čvorova
{1, 2, . . . , n}. Tada je težinska matrica grafa G (engl. weight matrix), u oznaci
W (G), matrica [wi j ] formata n × n takva da je
(
0, čvorovi i i j nisu susedni,
wi j =
k, čvorovi i i j su susedni i k > 0 je težina grane {i, j}

Matrica W (G) je uvek simetrična. Na primer:

1
1 3
8 W (G) 0 1 2 3 4 5
2 21 9 5 0 0 8 21 17 6 9
G= 0 1 8 0 1 0 0 3
2 21 1 0 4 0 0
4 17 6 7
3 17 0 4 0 12 0
4 6 0 0 12 0 7
3 12
4 5 9 3 0 0 7 0
4.3. RASTOJANJA U GRAFU 49

Težinske grafove predstavljamo kao “obične grafove”, s tim što sada matrica
susedstva umesto brojeva 0 (nisu susedni) i 1 (jesu susedni) sadrži 0 kada čvorovi
nisu susedni i strogo pozitivni vrednost kada su čvorovi susedni. Ova pozitivna
vrednost predstavlja težinu grane. Implementacija klase Graf koju smo do sada
koristi ispunjava sve ove zahteve. Potrebno joj je dodati samo još nekoliko metoda
koji su specifični za rad sa težinskim grafovima.
// vraca tezinu grane uv
public int tezina( int u, int v) { return A[u][v ]; }

// dodaje grafu granu uv sa tezinom w


public void dodajGranu(int u, int v, int w){
D[u]++; D[v]++; M++;
A[u][v] = w; A[v ][ u] = w;
}

4.3 Rastojanja u grafu


U ovom odeljku bavimo se problemom nalaženja najkraćeg puta izmedu čvorova
povezanog težinskog grafa. Pokazaćemo dva fundamentalna algoritma:

• Floydov algoritam koji nalazi rastojanje svaka dva čvora u grafu (all-pairs
shortest path problem); i

• Dijkstrin algoritam koji za dati čvor nalazi rastojanje od njega do svakog


drugog čvora u grafu (single-source shortest path problem).

4.3.1 Floydov algoritam


Floydov algoritam predstavlja efikasan način da se nade najkraće rastojanje
svaka dva čvora u povezanom težinskom grafu. Neka nam je dat težinski graf
(G, w) sa n čvorova i neka je W = [wi j ] njegova težinska matrica. Floydov algori-
tam u n koraka odreduje matricu D = [di j ] tako da je di j > 0 dužina najkraćeg puta
koji spaja čvorove i i j.
(k)
Ako sa D(k) = [di j ] označimo sadržaj matrice D u k-tom koraku algoritma,
onda je D(0) = W , a za k > 1:
(k)
di j = dužina najkraćeg puta koji spaja čvorove i i j,
a koji prolazi samo kroz čvorove 1, . . . , k.
50 GLAVA 4. TEŽINSKI GRAFOVI

Zapravo, pri prelasku sa (k − 1)-og na k-ti korak pokušavamo da utvrdimo da li


postoji kraći put koji ide od i do j preko k, odnosno, da li se umetanjem čvora k
može postići kraće rastojanje. Pri tome se u osnovi koristimo sledećom činjenicom:

(k−1)
k (k−1)
 dik dk j
(k−1)
 di j

(k)
di j = min i j

 d (k−1) + d (k−1) (k−1)
ik kj di j
(k)
Ako su sva tri puta na slici postoje u (k − 1)-om koraku, onda se vrednost di j
računa kako je navedeno. Na Sl. 4.1 pokazano je kako se ponašamo kada neki od
ovih puteva ne postoji u k-tom koraku. (Da se podsetimo, u (k − 1)-om koraku
računamo dužinu najkraćeg puta koji spaja čvorove i i j, a koji prolazi samo kroz
čvorove 1, . . . , k − 1; prema tome, može se desiti da za neki par čvorova i i j ne
postoji put koji ih spaja, a prolazi samo kroz čvorove 1, . . . , k − 1).
Pošto obračun vršimo samo za slučaj i 6= j 6= k 6= i, lako se vidi da se tokom k-
tog koraka ne menja nijedno polje matrice D oblika dik ili dk j . Zato se ceo postupak
može izvršiti u jednoj matrici i procedura koja to radi je veoma jednostavna.
public int [][] Floyd() {
int [][] D = new int[N][N];
int i , j , k;
for( i = 0; i < N; i++)
for( j = 0; j < N; j++)
D[i ][ j ] = tezina( i , j );

for(k = 0; i < N; i++)


for( i = 0; i < N; i++)
for( j = 0; j < N; j++)
if (
i != j && i != k && j != k && D[i ][ k] != 0 && D[k][j ] != 0
&&(D[i][ j ] == 0 || D[i ][ k] + D[k][ j ] < D[i ][ j ])
) {
D[i ][ j ] = D[i ][ k] + D[k ][ j ];
}
return D;
}
(k−1) (k−1) (k−1)
Kao što smo videli, vrednost di j treba promeniti ako je di j > dik + dk j .
Ova nejednakost, medutim, ima smisla samo ako sva tri najkraća puta preko čvorova
(k−1) k k (k−1) k

4.3. RASTOJANJA U GRAFU


dik dk j

i j i j i j
(k−1) (k−1) (k−1)
di j di j di j

(k) (k−1)
di j = di j , odnosno, ne treba menjati di j

(k−1) k (k−1)
dk j
dik

i j

(k) (k−1) (k−1)


di j = dik + dk j

(k−1) k k (k−1)
dk j k
dik

i j i j i j

(k)
di j = 0, odnosno, ne treba menjati di j

51
Slika 4.1: Obračun najkraćeg puta u Floydovom algoritmu u slučajevima kada neke od dužina još nisu izračunate
52 GLAVA 4. TEŽINSKI GRAFOVI

1, . . . , k − 1 postoje, tj. ukoliko je svaki od navedena tri broja strogo pozitivan. Ako
bar jedan od najkraćih puteva ne postoji, nastao je neki od patoloških slučajeva sa
Sl. 4.1 i vrednost di j treba ažurirati samo u jednom slučaju.

4.4 Minimalno pokrivajuće stablo


Podsetimo se da se podgraf T zove pokrivajuće stablo grafa G ako je T podgraf
grafa koji je stablo i za koga je V (T ) = V (G). Kao što znamo, graf ima pokrivajuće
stablo ako i samo ako je povezan, i tada se jedno njegovo pokrivajuće stablo može
naći DFS algoritmom. Ukoliko radimo sa težinskim grafovima, često je važno
imati algoritam koji za dati povezan težinski graf traži pokrivajuće stablo najmanje
težine.

Definicija 4.3 Minimalno pokrivajuće stablo povezanog težinskog grafa (G, w) je


pokrivajuće stablo T0 grafa G sa osobinom da za svako drugo pokrivajuće stablo T
grafa G važi w(T0 ) 6 w(T ).

Jasno je da svaki povezan težinski graf ima minimalno pokrivajuće stablo,


mada ono ne mora biti jedinstveno. Primov algoritam je jedan efikasan algori-
tam koji nalazi minimalno pokrivajuće stablo povezanog težinskog grafa. Ideja
Primovog algoritma je jednostavna. Podemo od proizvoljnog čvora grafa—to je
početno stablo (mada još uvek ne pokriva mnogo). Sada n(G) − 1 puta ponovimo
sledeći korak:

od svih grana koje imaju jedan čvor u skupu do sada odabranih čvorova,
a drugi izvan, nademo onu koja ima najmanju težinu i dodamo tu granu
stablu.

U svakom koraku stablo poraste za jedan čvor. Na kraju dobijamo pokrivajuće


stablo polaznog povezanog grafa za koga ćemo pokazati da je zaista minimalno.
Metod Prim za dati povezani težinski graf G odreduje podgraf T koji je mini-
malno pokrivajuće stablo grafa G.
// metod klase Graf; poziva se ovako: T = G.Prim();
public Graf Prim() {
Graf T = new Graf(N);

boolean[] uStablu = new boolean[N];


uStablu[0] = true;
for( int i = 1; i < N; i++) uStablu[i ] = false;
4.4. MINIMALNO POKRIVAJUĆE STABLO 53

while(T.brGrana() < N − 1){


// nadji najlaksu granu ciji jedan kraj je u stablu a drugi nije
boolean nasao = false;
int u = 0, v = 0, w = 0;
for( int i = 0; i < N − 1; i++)
for( int j = i + 1; j < N; j++)
if (
(uStablu[i ] && !uStablu[j ] || uStablu[j ] && !uStablu[i ])
&& susedni(i, j )
) {
if (nasao){
if (tezina( i , j ) < w) { u = i ; v = j ; w = tezina( i , j ); }
}
else {
u = i ; v = j ; w = tezina( i , j );
nasao = true;
}
}
// dodaj tu granu u stablo
T.dodajGranu(u, v, w);
if (! uStablu[u]) uStablu[u] = true;
if (! uStablu[v ]) uStablu[v] = true;
}
return T;
}

Prelazimo sada na dokaz korektnosti algoritma.

Lema 4.4 Primovim algoritmom se dobija pokrivajuće stablo polaznog grafa.

Dokaz. U svakom koraku algoritma podgrafu T (koji polako raste) dodajemo jedan
novi čvor v i jednu novu granu koja v spaja sa čvorom u koji je već u podgrafu.
Time je obezbedeno da nijedna nova grana ne zatvori konturu u podgrafu T . Dakle,
na kraju rada algoritma dobijamo podgraf T grafa G koji nema konture, ima n
čvorova i n − 1 granu. Prema Teoremi 3.8 podgraf T je stablo. Kako T i G imaju
isti broj čvorova, T je pokrivajuće stablo grafa G. 

Teorema 4.5 Pokrivajuće stablo dobijeno Primovim algoritmom je minimalno po-


krivajuće stablo polaznog grafa.
54 GLAVA 4. TEŽINSKI GRAFOVI

Dokaz. Neka je (G, w) povezan težinski graf. Neka je e1 , e2 , . . . , en−1 niz grana, a
T0 , T1 , . . . , Tn−1 niz stabala koji se dobijaju u Primovom algoritmu. Jasno je da se
T0 sastoji samo od jednog čvora i da je E(Tk ) = {e1 , . . . , ek } za k = 1, 2, . . . , n − 1.
Pokažimo da za svako k = 0, 1, . . . , n−1 postoji minimalno pokrivajuće stablo grafa
G koje kao svoj podgraf sadrži stablo Tk . Dokaz provodimo indukcijom po k.
Neka je M proizvoljno minimalno pokrivajuće stablo grafa G. Ono sadrži sve
čvorove grafa, pa i čvor od koga se sastoji graf T0 . Ovim je tvrdenje pokazano za
k = 0.
Pretpostavimo da je tvrdenje tačno za k i neka je M minimalno pokrivajuće
stablo koje kao svoj podgraf sadrži Tk . Uočimo da stablo Tk+1 ima samo jednu
granu više od stabla Tk . To je grana ek+1 . Ako stablo M sadrži i granu ek+1 , dokaz
je završen: M je minimalno pokrivajuće stablo grafa koje sadrži Tk+1 kao svoj
podgraf. Ako stablo M ne sadrži granu ek+1 , situacija se malo komplikuje.
Neka je ek+1 = {u, v} pri čemu se čvor u nalazi
u V (Tk ), a čvor v u V (G) \V (Tk ). Kako je M pokri- M
Tk
vajuće stablo grafa G, ono sadrži sve čvorove grafa
G, pa i čvorove u i v. Zbog povezanosti grafa M u′ v′
postoji put u M koji počinje u čvoru u, a završava
se u čvoru v. Kako se čvor u nalazi u V (Tk ), a čvor
v u V (G) \V (Tk ), to put u M koji spaja u i v mora
sadržati granu koja takode ima jedan čvor u V (Tk )
u v
a drugi izvan. Neka je to grana e′ = {u′ , v′ } i neka
je u′ ∈ V (Tk ), a v′ izvan. Prema tome, kako je grana
ek+1 birana dobijamo da je w(ek+1 ) 6 w(e′ ).
Posmatrajmo graf M ′ koji se dobija tako što se iz grafa M izbaci grana e′ i ubaci
grana ek+1 . Graf M ′ nema kontura, ima n čvorova i n − 1 granu pa je to stablo.
Kako i M ′ pokriva sve čvorove grafa G zaključujemo da je M ′ pokrivajuće stablo.
Pokažimo da je M ′ minimalno pokrivajuće stablo grafa G. Zbog w(ek+1 ) 6 w(e′ )
i činjenice da se M i M ′ razlikuju samo po tome što je iz M izbačena grana e′ i
ubačena grana ek+1 odmah se vidi da je w(M ′ ) 6 w(M). No, kako je M minimalno
pokrivajuće stablo, to znači da ne može postojati drugo pokrivajuće stablo koje je
od njega lakše. Zato mora biti w(M ′ ) = w(M). Odavde se vidi da je i M ′ minimalno
pokrivajuće stablo grafa G.
Dakle, za svako k = 0, 1, . . . , n − 1 postoji minimalno pokrivajuće stablo koje
kao svoj podgraf sadrži graf Tk . Zato, postoji minimalno pokrivajuće stablo M koje
kao svoj podgraf sadrži graf Tn−1 . Kako i M i Tn−1 imaju po n čvorova i n − 1
granu i kako je Tn−1 podgraf od M, mora biti Tn−1 = M. Zato je Tn−1 minimalno
pokrivajuće stablo grafa G. 

Kada analiziramo Primov algoritam vidimo jednu interesantnu stvar: on u sva-


kom koraku bira granu koja je u tom trenutku najlakša. Algoritam ni ne pokušava
ZADACI ZA VEŽBU 55

da planira unapred, da dublje analizira situaciju, već grabi granu koja je u tom tre-
nutku najpovoljnija. Reklo bi se da je ogromna sreća da na kraju dobijemo baš ono
što nam je trebalo!
Algoritmi koji ne planiraju ništa unapred, već grabe ono što je u tom trenutku
najpovoljnije zovu se pohlepni algoritmi (engl. greedy algorithms). Nema mnogo
problema kod kojih pohlepni algoritmi daju optimalna rešenja. U mnogim situ-
acijama (npr. kao u šahu) ponekad je potrebno uraditi nešto što u tom trenutku
ne deluje najpovoljnije, a kasnije se ispostavi da je to bilo mudro i da zbog toga
možemo dobiti optimalno rešenje.

Zadaci za vežbu
4.1. Za težinski graf kažemo da je magičan ako postoji konstanta k takva da za
svaki čvor v, suma težina grana koje su incidentne sa v jednaka je k. Napi-
sati metod magican koji za dati težinski graf utvrduje da li je on magičan.
4.2. Napisati metod tezinaPodgrafa koji za dati težinski graf G i skup čvorova
S ⊆ V (G) odreduje zbir težina svih grana čija oba kraja su u S.
4.3. Ekscentricitet čvora v u težinskom grafu G je najveće moguće rastoja-
nje od čvora v do nekog drugog čvora u grafu. Čvor v je centralni čvor
težinskog grafa G ako ima najmanji mogući ekscentricitet. Napisati pro-
gram koji za dati težinski graf G odreduje skup svih njegovih centralnih
čvorova.
4.4. Napisati program koji za običan, dakle ne težinski, graf G odreduje sve
parove (x, y) čvorova sa osobinom da postoji šetnja dužine tačno k koja
spaja x sa y. Primetimo da u tom slučaju možda postoji i kraća šetnja, ali
to nije bitno.
(Uputstvo: Neka je A matrica susedstva grafa G. Šta predstavljaju elementi
matrice A2 ? Matrice A3 ? . . . Matrice Ak ?)
4.5. Napisati program koji za običan, dakle ne težinski, graf G računa matricu
D = [di j ] logičkih vrednosti tako da je
di j = true ako i samo ako postoji put od i do j u G.

(Uputstvo: Algoritam koji rešava ovaj problem dobija se jednostavnom


modifikacijom Floydovog algoritma gde iteriranje treba obaviti koristeći
sledeće
(k) (k−1) (k−1) (k−1) 
di j = di j or dik and dk j
Ova modifikacija Floydovog algoritma se zove Warshallov algoritam.)

Vous aimerez peut-être aussi