You are on page 1of 30

1

GRAFURI ORIENTATE


ASPECTE TEORETICE

1. Noiunea de graf orientat

Definiie. Se numete graf orientat o pereche ordonat de mulimi notat G=(V, U), unde:
V : este o mulime, finit i nevid, ale crei elemente se numesc noduri sau vrfuri;
U : este o mulime, de perechi ordonate de elemente distincte din V, ale crei elemente se numesc arce.
Exemplu de graf orientat:
G=(V, U) unde: V={ 1,2,3,4}
U={{1,2}, {2,3},{1,4}}
Demonstraie:
Perechea G este graf orientat deoarece respect ntocmai definiia prezentat mai sus, adic:
V : este finit i nevid:
U : este o mulime de perechi ordonate de elemente din V.

n continuare, vom nota submulimea {x,y}, care reprezint un arc, cu ( x,y) (ntr-un graf orientat arcul (x,y)
este diferit de arcul ( y,x)). n baza celor spuse anterior, graful prezentat n exemplul de mai sus se reprezint
textual astfel:
G=(V, U) unde: V={ 1,2,3,4}
U={(1,2), (2,3), (1,4) }
n teoria grafurilor orientate se ntlnesc frecvent noiunile:
- extremitile unui arc
fiind dat arcul u=(x,y), se numesc extremiti ale sale nodurile x i y;
x se numete extremitate iniial;
y se numete extremitate final.
- vrfuri adiacente
dac ntr-un graf exist arcul u=(x,y) (sau u=(y,x), sau amndou), se spune despre nodurile x i y c sunt
adiacente;
- inciden
dac ul i u2 sunt dou arce ale aceluiai graf, se numesc incidente dac au o extremitate comun.
Exemplu. u1=(x,y) i u2=(y,z) sunt incidente;
dac u1=(x,y) este un arc ntr-un graf, se spune despre el i nodul x, sau nodul y, c sunt incidente.

Reprezentarea unui graf orientat admite dou forme, i anume:
- reprezentare textual: aa cum s-a reprezentat graful din exemplul anterior;
- reprezentare grafic : arcele sunt reprezentate prin sgei orientate, iar nodurile prin puncte.
Exemplu de graf orientat reprezentat textual:
G=(V, U) unde: V={ 1,2,3,4}
U={(1,2), (2,3), (1,4), (4,1)}
Exemplu de graf orientat reprezentat grafic (este graful de la exemplul anterior):
1

Alte definiii

Definiie. Se numete graf orientat o pereche ordonat de mulimi notat G=(V, U), unde:
V : este o mulime, finit i nevid, ale crei elemente se numesc noduri sau vrfuri;
U : este o mulime, de perechi ordonate de elemente din V, ale crei elemente se numesc arce.
2
Aceast definiie difer de prima definiie prin faptul ca acum nu se mai spune despre extremitile unui arc
ca trebuie s fie distincte. n baza acestei definiii, sunt permise i arce de genul: u=(x,x) unde xV; aceste
arce se numesc bucle.
Exemplu de graf orientat (reprezentat grafic):
V={1,2,3,4} U={(1,2),(2,3),(1,4), (4,4)}
1


Definiie. Se numete graf orientat o pereche ordonat de mulimi notat G=(V, U), unde:
V : este o mulime, finit i nevid, ale crei elemente se numesc noduri sau vrfuri;
U : este o familie de perechi ordonate de elemente din V, numit familia de arce.
Aceast definiie difer de cea anterioar prin faptul ca acum nu numai c se admit bucle, dar se admit i mai
multe arce identice.
Exemplu de graf orientat (reprezentat grafic):
V={1,2 3,4}
U={(1,2), (1,2), (2,1), (1,4), (2,3), (4,4)}
1


Observaie. Dac ntr-un graf orientat numrul arcelor identice nu depete numrul p, atunci se
numete p-graf.

2. Noiunea de graf parial

Definiie. Fie G=(V, U) un graf orientat. Se numete graf parial, al grafului G, graful orientat G
1
=(V, U
1
)
unde U
1
U.
Atenie! Citind cu atenie definiia, de mai sus, tragem concluzia:
Un graf parial, al unui graf orientat G=(V, U), are aceeai mulime de vrfuri ca i G, iar mulimea arcelor
este o submulime a lui U sau chiar U.
Exemplu: Fie graful orientat
G=(V, U) unde: V={ 1,2,3,4}
U={(1,2), (l,4), (2,3)}
reprezentat grafic astfel:

1. Un exemplu de graf parial al grafului G este
graful orientat:
G
1
=(V, U
1
) unde: V={ 1,2,3,4}
U
1
={(1,2),(1,4)}
(s-a eliminat arcul (2,3))
reprezentat grafic astfel:
1

3
2. Un exemplu de graf parial al grafului G este
graful orientat:
reprezentat grafic astfel:
G
1
=(V, U) unde: V={ 1,2,3,4}
U
1
=
(s-au eliminat toate arcele)
1
4
2
3
3
Observaie. Fie G=(V, U) un graf orientat. Un graf parial, al grafului G, se obine pstrnd vrfurile i
eliminnd eventual nite arce (se pot elimina i toate arcele sau chiar nici unul).

3. Noiunea de subgraf

Definiie. Fie G=(V, U) un graf orientat. Se numete subgraf, al grafului G, graful orientat G
1
=(V
1
,U
1
)
unde V
1
V iar U
1
conine toate arcele din U care au extremitile n V
1
.
Exemplu: Fie graful orientat
G=(V, U) unde: V={ 1,2,3,4}
U={(1,2), (2,3), (1,4)}
reprezentat grafic astfel:

1. Un exemplu de subgraf al grafului G este
graful orientat:
G
1
=(V
1
, U
1
) unde: V
1
={1,2,3}
(s-a ters nodul4)
U
1
={(1,2),(2,3)}
(s-a eliminat arcul (1,4))
reprezentat grafic astfel:

2. Un exemplu de subgraf al grafului G este graful
orientat:
G
1
=(V
1
, U
1
) unde: V
1
={2,3,4}
(s-a eliminat nodul 1)
U
1
={(2,3)}
(s-au eliminat arcele (1,4) (1,2))
reprezentat grafic astfel:
4


Observaie. Fie G=(V, U) un graf orientat. Un subgraf, al grafului G, se obine tergnd eventual anumite
vrfuri i odat cu acestea i arcele care le admit ca extremitate (nu se pot terge toate vrfurile deoarece
s-ar obine un graf cu mulimea vrfurilor vid).

4. Gradul unui vrf

Avnd la baz ideea c "raportat la un vrf exist arce care ies din acel vrf i arce care intr n acel vrf, au
luat natere urmtoarele noiuni:
- grad exterior
- grad interior
care vor fi prezentate in continuare.

Grad exterior

Definiie. Fie G=(V, U) un graf orientat si x un nod al su. Se numete grad exterior al nodului x, numrul
arcelor de forma (x,y) (adic numrul arcelor care ies din x), notat d
+
(x).
Exemplu: Fie graful orientat:
G=(V, U) unde: V={ 1,2,3,4}
U={(1,2), (1,2), (2,1), (1,4), (2,3)> (4,4)}
reprezentat grafic astfel:
1

Gradul exterior al nodului 1 este d
+
(1)=3 (n graf, sunt trei arce care ies din 1).
Gradul exterior al nodului 2 este d
+
(2)=2 (n graf, sunt dou arce care ies din 2).
4
Gradul exterior al nodului 3 este d
+
(3)=0 (n graf, nu sunt arce care ies din 3).
Gradul exterior al nodului 4 este d
+
(4)=1 (n graf, este un arc care iese din 4 (bucla)).
Observaii.
1. Mulimea succesorilor lui x se noteaz cu
+
(x) i se reprezint astfel:
( ) ( ) { } U y x V y x =
+
,
2. Mulimea arcelor ce ies din x se noteaz cu
+
(x) i se reprezint astfel:
( ) ( ) { } V y U y x x =
+
,
3. Legat de cardinalele mulimilor
+
(x) i
+
(x) putem scrie:
( ) ( ) ( ) x d x x
+ + +
= =
Raportat la graful prezentat n figura de mai jos,
1


putem scrie:

+
(1)={2, 4}
+
(1)={(1,2), (1,4)} ( ) ( ) ( ) 2 1 1 1 = = =
+ + +
d

+
(2)={1, 3}
+
(2)={(2,1), (2,3)} ( ) ( ) ( ) 2 2 2 2 = = =
+ + +
d

+
(3)=
+
(3)= ( ) ( ) ( ) 0 3 3 3 = = =
+ + +
d

+
(4)={4}
+
(4)=f (4,4)} ( ) ( ) ( ) 1 4 4 4 = = =
+ + +
d

Grad interior

Definiie. Fie G=(V, U) un graf orientat i x un nod al su. Se numete grad interior al nodului x, numrul
arcelor de forma (y,x) ( adic numrul arcelor care intr in x), notat d
-
(x).
Exemplu: Fie graful orientat
G=(V, U) unde: V={ 1,2,3,4}
U= {(1,2), (1,2), (2,1), (1,4), (2,3), (4,4)}

reprezentat grafic astfel:


Gradul interior al nodului 1 este d
-
(1)=1 (n graf, este un arc care intr n 1).
Gradul interior al nodului 2 este d
-
(2)=2 (n graf, sunt dou arce care intr n 2).
Gradul interior al nodului 3 este d
-
(3)=1 (n graf, este un arc care intr n 3).
Gradul interior al nodului 4 este d
-
(4)=2 (n graf, sunt dou arce care intr n 4).
Observaii.
1. Mulimea predecesorilor lui x se noteaz cu
-
(x) i se reprezint astfel:
( ) ( ) { } U x y V y x =

,
2. Mulimea arcelor ce intr in x se noteaz cu
-
(x) i se reprezint astfel:
( ) ( ) { } V x U x y x =

,
3. Legat de cardinalele mulimilor
-
(x) i
-
(x) putem scrie:
( ) ( ) ( ) x d x x

= =
Raportat la graful prezentat n figura de mai jos,
1
5

putem scrie:

-
(1)={2}
-
(1)={(2,1)} ( ) ( ) ( ) 1 1 1 1 = = =

d

-
(2)={1}
-
(2)={(1,2)} ( ) ( ) ( ) 1 2 2 2 = = =

d

-
(3)={2}
-
(3) = {(2,3)} ( ) ( ) ( ) 1 3 3 3 = = =

d

-
(4)={1,4}
-
(4)={(1,4),(4,4)} ( ) ( ) ( ) 2 4 4 4 = = =

d

Observaie. Un nod se numete izolat dac:
d
+
(x)=d
-
(x)=0
Propoziie. n graful orientat G=(V, U), n care V={x
1
, x
2
, ...,x
n
} i sunt m arce, se verific egalitatea :
( ) ( ) m x d x d
n
i
i
n
i
i
= =

=

=
+
1 1


5. Graf complet. Graf turneu

Definiie. Fie G=(V, U) un graf orientat. Graful G se numete graf complet dac oricare dou vrfuri
distincte ale sale sunt adiacente.
Dou vrfuri x i y sunt adiacente dac:
- ntre ele exist arcul (x,y), sau
- ntre ele exist arcul (y,x), sau
- ntre ele exist arcele (x,y) i (y,x).

Exemplu de graf orientat complet:
G=(V, U) unde: V={1,2,3,4}
U={(1,2),,(1,3), (1,4), (2,3), (2,4), (3,4)}
Reprezentarea sa grafic este:
1

Propoziie. ntr-un graf complet cu n vrfuri, exist ntre
2
) 1 ( n n
i n(n-1) arce. (U este privit ca o mulime
(prima definiie a grafului) nu ca o familie)

Demonstraie: Numrul cel mai mic de arce, cnd graful este complet, se obine atunci cnd nodurile sunt
unite doar printr-un singur arc i se determin astfel:
Pentru fiecare vrf x
i
, numrul arcelor care intr i ies este n-1, deci d
+
(x
i
)+ d
-
(x
i
)=n-1, pentru orice i=1..n.
nsumnd toate aceste relaii, obinem:
( ) ( ) ( ) ( ) ( ) ( ) ) 1 ( 1
1 1 1 1
= + = +

=

=
+
= =
+
n n x d x d n x d x d
n
i
i
n
i
i
n
i
n
i
i i
(1)
innd cont de faptul c:
( ) ( ) m x d x d
n
i
i
n
i
i
= =

=

=
+
1 1

relaia (1) devine:

( )
2
1
) 1 (

= = +
n n
m n n m m
6
Numrul cel mai mare de arce, cnd graful este complet, se obine atunci cnd nodurile sunt unite prin dou
arce, adic pentru nodurile x i y exist arcele (x,y) i (y,x), i este egal cu
( )
( ) 1
2
1
2 =

n n
n n

Lema Avem
( )
2
1
3
n n
grafuri complete cu n noduri.
Definiie Un graf orientat este turneu, dac oricare ar fi 2 vrfuri i i j, ij, ntre ele exist un singur arc:
arcul(i,j) sau arcul (j,i)
Proprieti:
1. Orice graf turneu este graf complet.
2. Avem
( )
2
1
2
n n
grafuri turneu cu n noduri
3. n orice graf turneu exist un drum elementar care trece prin toate vrfurile grafului.

Problem. Fiind dat un graf turneu, se cere s se afieze un drum elementar care trece prin toate vrfurile.
#include<iostream.h>
#include<conio.h>
int s[20],a[20][20],n,L,i,j;
void afisare_drum()
{int i; cout<<endl;
for(i=1;i<=n;i++)
cout<<s[i]<<" ";}
void generare_drum()
{int i,j,k,p,q;
if(a[1][2]==1) {s[1]=1;s[2]=2;}
else{s[1]=2;s[2]=1;}
L=2;
for(k=3;k<=n;k++)
{if(a[k][s[1]]==1) p=1;
else{i=1;q=0;
while(i<L&&!q)
if(a[s[i]][k]==1&&a[k][s[i+1]]==1) q=1;
else i++;
p=i+1;}
for(j=L;j>=p;j--) s[j+1]=s[j];
s[p]=k;
L++;}
cout<<endl;}
void main()
{
cout<<"n=";cin>>n;
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++)
{cout<<"exista arcul ("<<i<<","<<j<<")?[1/0]";
do{
cin>>a[i][j];
} while(!(a[i][j]==0 || a[i][j]==1));
a[j][i]=1-a[i][j];}
generare_drum();
afisare_drum();
getch();}




4
3
2
1
7
6. Conexitate

n aceast seciune, vor fi prezentate noiunile:
- lan
- drum
- circuit
- graf conex
- component conex

Lan

Definiie. Fie G=(V, U) un graf orientat. Se numete lan, n graful G, o succesiune de arce, notat
[ ]
k
i i i
u u u L ,..., ,
2 1
= cu proprietatea ca oricare dou arce consecutive au o extremitate comun (nu are
importan orientarea arcelor).
Se ntlnesc noiunile:
- extremitile lanului
fiind dat lanul [ ]
k
i i i
u u u L ,..., ,
2 1
= se numesc extremiti ale sale extremitatea arcului u
i1
care nu este
comun cu arcul u
i2
i extremitatea arcului u
ik
care nu este comun cu arcul u
ik-1
- lungimea lanului
fiind dat lanul [ ]
k
i i i
u u u L ,..., ,
2 1
= prin lungimea sa se nelege numrul de arce care apar n L;
Exemplu de lan:
cu reprezentarea grafic astfel:
Fie graful G=(V, U), unde: V={1,2,3,4,5}
U={(1,3),(1,4), (2,3), (2,4), (5,2)}=
{ u
1
, u
2
, u
3
, u
4
, u
5
}
1



L1=[ u
1
,u
3
,u
5
] este, n graful G, lan cu lungimea 3 i extremitile 1 i 5.
L2=[ u
1
,u
2
, u
4
, u
5
] este, n graful G, lan cu lungimea 4 i extremitile 3 i 5.

Atenie! Dac [ ]
k
i i i
u u u L ,..., ,
2 1
= este lan n graful G, atunci i [ ]
1 1
,..., ,
1 i i i
u u u L
k k
= este lan n graful G.

Drum

Definiie. Fie G=(V, U) un graf orientat. Se numete drum, n graful G, o succesiune de noduri, notat
( )
k
i i i
x x x D ,..., ,
2 1
= , cu proprietatea( ) ( ) U x x x x
k k
i i i i

, ,..., ,
1 2 1
(altfel spus ( ) ( )
k k
i i i i
x x x x , ,..., ,
1 2 1
sunt arce).
Se ntlnesc noiunile:
- extremitile drumului
fiind dat drumul ( )
k
i i i
x x x D ,..., ,
2 1
= se numesc extremiti ale sale nodurile x
i1
i x
ik
(x
i1
extremitate iniial

i x
ik
extremitate final)
- lungimea drumului
fiind dat drumul ( )
k
i i i
x x x D ,..., ,
2 1
= , prin lungimea sa se nelege numrul de arce care apar n cadrul
su;
Exemplu de drum:
Fie graful G=(V, U) unde:
V={ 1,2,3,4,5 }
U={(1,3), (4,1), (3,2), (2,4), (5,2)}
cu reprezentarea grafic astfel:
8

D1=(1, 3, 2) este, n graful G, drum cu lungimea 2 i extremitile 1 i 2.
D2=(4, 1, 3, 2) este, n graful G, drum cu lungimea 3 i extremitile 4 i 2.
Atenie! Dac ( )
k
i i i
x x x D ,..., ,
2 1
= este drum, n graful G, atunci nu neaprat i ( )
1
,..., , 1
1 i ik i
x x x D
k

= este drum,
n graful G.

Definiie. Fie G=(V,U) un graf orientat. Se numete drum elementar, n graful G, drumul
( )
k
i i i
x x x D ,..., ,
2 1
= cu proprietatea c oricare dou noduri ale sale sunt distincte (altfel spus, printr-un nod
nu se trece dect o singur dat).
Exemplu: n graful de mai jos,
1

3
drumul D1=(4, 1, 3, 2) este drum elementar.

Definiie. Fie G=(V, U) un graf orientat: Se numete drum neelementar, n graful G, drumul
( )
k
i i i
x x x D ,..., ,
2 1
= cu proprietatea c nodurile sale nu sunt distincte dou cte dou (altfel spus, prin anumite
noduri s-a trecut de mai multe ori).
Exemplu: n graful de mai jos,
1

drumul D2=(4, 1, 3, 2, 4, 5, 2) este drum neelementar (prin 4 (i 2) s-a trecut de dou ori).

Circuit

Definiie: Fie G=(V, I) un graf neorientat. Se numete circuit, n graful G, drumul ( )
k
i i i
x x x D ,..., ,
2 1
= cu
proprietatea c x
i1
= x
ik
i are arcele cel compun diferite dou cte dou (circuitul se noteaz n continuare cu
C).
Exemplu: n graful de mai jos,
1

3
drumul C=(1, 3, 2, 4, 1) este circuit.
Definiie. Fie G=(V, U) un graf orientat. Se numete circuit elementar, n graful G, un circuit cu
proprietatea c oricare dou noduri ale sale, cu excepia primului i a ultimului, sunt distincte.
Exemplu: n graful de mai jos,
1

3
circuitul C=(1, 3, 2, 4, 1) este circuit elementar.
9
Definiie. Fie G=(V, U) un graf orientat. Se numete circuit neelementar, n graful G, un circuit cu
proprietatea c nodurile sale, cu excepia primului i a ultimului, nu sunt distincte.
Exemplu: n graful de mai jos
1

circuitul C=(1, 3, 4, 2, 5, 4, 1) este circuit neelementar (prin 4 s-a trecut de dou ori).

Graf conex

Definiie. Fie G=(V, U) un graf orientat. Graful G se numete conex dac pentru oricare dou vrfuri x i y,
x#y, exist un lan de extremiti x i y.
Exemplu de graf care este conex:

3
Graful este conex, deoarece oricare ar fi vrfurile x i y, x#y, exist un lan in G care s le lege.
Exemplu de graf care nu este conex:
1

2

Graful nu este conex, deoarece exist dou vrfuri, cum ar fi 1 i 4, pentru care nu exist nici un lan n graf
care s le lege.

Component conex

Definiie. Fie G=(V, U) un graf orientat. Se numete component conex un graf orientat G
1
=(V
1
,U
1
) care
verific urmtoarele condiii:
- este subgraf al grafului G;
- este conex;
- nu exist nici un lan n G care s lege un nod din V, cu an nod din V-V
1
.
Exemplu: Fie graful G=(V, U) : V={1,2,3,4,5} i U={(1,2), (3,1), (3,2), (4,5)}
1

2


Pentru graful de mai sus, graful G1=(V1,U1) unde: V1={4,5} i U1={(4,5)} este component conex,
deoarece:
- este subgraf al grafului G;
- este conex;
- nu exist nici un lan n G care s lege un nod din V, cu un nod din V-V
1
={1,2,3}
La fel, se poate spune i despre graful G2=(V2,U2) unde: V2={1,2,3) i U2={(1,2)> (3,1), (3,2)}
n concluzie, graful din figura de mai sus este format din dou componente conexe.
Observaie. Fie G=(V, U) un graf orientat. Graful G este conex dac i numai dac este format dintr-o
singur component conex.
Exemplu de graf conex (este format dintr-o singur component conex):
10

7. Reprezentarea grafurilor orientate

Fie G=(V, U) un graf orientat, unde V={x
1
, x
2
,..., x
n
} i U={u
1
, u
2
,..., u
m
} . Deoarece ntre mulimea {x
1
,
x
2
,..., x
n
} i mulimea {1, 2,..., n} exist o bijecie, x
i
i, putem presupune, fr a restrnge generalitatea,
mai ales pentru a uura scrierea, c V={1, 2,..., n}.
n baza celor spuse mai sus, mai departe, n loc de x
i
vom scrie i, i n loc de arcul (x
i
,x
j
) vom scrie (i ,j).
Pentru a putea prelucra un graf orientat cu ajutorul unui program, trebuie mai nti s fie reprezentat n
programul respectiv.
Pentru a reprezenta un graf orientat, ntr-un program, exist mai multe modaliti folosind diverse structuri
de date; dintre acestea n continuare vom prezenta:
- reprezentarea prin matricea de adiacen;
- reprezentarea prin matricea vrfuri-arce;
- reprezentarea prin matricea drumurilor;
- reprezentarea prin listele de adiacen;
- reprezentarea prin irul arcelor.

Matricea de adiacen

Fie G=(V; U) un graf orientat cu n vrfuri (V={ 1,2, ..., n}) i m arce.
Matricea de adiacen (AM
n
({0,1})), asociat grafului G, este o matrice ptratic de ordin n, cu
elementele:
( )
( )

=
U j i daca
U j i daca
a
j i
, , 0
, , 1
,

(altfel spus, a
i,j
=1, dac exist arc ntre i i j i a
i,j
=0 dac nu exist arc ntre i i j.
Exemplul 1.
Fie graful reprezentat ca n figura de mai jos:
1
2
3
Matricea de adiacen asociat grafului este:
|
|
|
|
|

\
|
=
|
|
|
|
|

\
|
=
0 0 0 1
0 0 0 0
1 1 0 0
0 1 0 0
44 43 42 41
34 33 32 31
24 23 22 21
14 13 12 11
a a a a
a a a a
a a a a
a a a a
A
Exemplul 2.
Fie graful reprezentat ca n figura de mai jos:
1
2
3
Matricea de adiacen asociat grafului este:
|
|
|
|
|

\
|
=
|
|
|
|
|

\
|
=
0 0 1 0
1 0 0 1
0 1 0 0
1 0 1 0
44 43 42 41
34 33 32 31
24 23 22 21
14 13 12 11
a a a a
a a a a
a a a a
a a a a
A
* Comentarii:
l. Matricea de adiacen este o matrice ptratic, de ordin n, i nu este neaprat simetric fa de diagonala
principal, aa cum este n cazul grafurilor neorientate.
Secvenele de citire a matricei de adiacen:
int a[100][100];
.................
cout<<"n="; cin>>n;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{cout"a[ "<<i<<,<<j<<]=; cina[i][j];}
sau:
cout<<"n m ; cin>>n>>m;
for (i=1;i<=m;i++)
{cout"dati extremitatile arcului "<<i<<" ; cin>>x>>y;
11
a[x][y]=1;}
....................
2. Matricea de adiacen are toate elementele de pe diagonala principal egale cu 0 (ne referim la definiia 1,
cnd graful nu are bucle).

3. Numrul elementelor egale cu 1 de pe linia i este egal cu gradul exterior al vrfului i.
int gr_ext(int i)
{int j , s;
s=0;
for (j=1;j<=n;j++) s=s+a[i][j];
return s;}

4. Numrul elementelor egale cu 1 de pe coloana i este egal cu gradul interior al vrfului i.
int gr int(int i)
{int j, s;
s=0;
for (j=1;j<=n;j++) s=s+a[j][i];
return s;}

5. Dac vrful i este un vrf izolat, pe linia i i coloana i nu sunt elemente egale cu 1.
int vf_izolat(int i)
{return (gr_ext(i)==0) && (gr_int(i)==0);
}

Matricea vrfuri-arce ( matricea de inciden)

Fie G=(V, U) un graf orientat cu n vrfuri (V={1,2, ..., n}) i m arce.
Matricea vrfuri-arce (BM
nxm
({-1,0,1})), asociat grafului G, este o matrice cu n linii i m coloane, cu
elementele:

=
j
j
j
j i
u arcul pentru initiala e extremitat este i daca
u arcul pentru extremiate este nu i daca
u arcul pentru finala e extremitat este i daca
b
, 1
, 0
, 1
,

Exemplul 1. Fie graful G=(V,U) :
V={1,2,3,4},
U={(1,3),(2,3),(2,4),(4,1)}= {u
1
, u
2
, u
3
, u
4
}
reprezentat ca in figura de mai jos:
1

3
Matricea vrfuri-arce asociat grafului este:
|
|
|
|
|

\
|

=
|
|
|
|
|

\
|
=
1 1 0 0
0 0 1 1
0 1 1 0
1 0 0 1
44 43 42 41
34 33 32 31
24 23 22 21
14 13 12 11
b b b b
b b b b
b b b b
b b b b
B





12
Exemplul 2. Fie graful G :
V={ 1,2,3,4},
U={(1,2),(1,4),(2,3),(3,1),(3,4),(4,2)}=
{u
1
, u
2
, u
3
, u
4
,u
5
, u
6
},
reprezentat ca n figura de mai jos:
1

3
Matricea vrfuri-arce asociat grafului este:
|
|
|
|
|

\
|

=
|
|
|
|
|

\
|
=
1 1 0 0 1 0
0 1 1 1 0 0
1 0 0 1 0 1
0 0 1 0 1 1
46 45 44 43 42 41
36 35 34 33 32 31
26 25 24 23 22 21
16 15 14 13 12 11
b b b b b b
b b b b b b
b b b b b b
b b b b b b
B
Comentarii:
1. Matricea vrfuri-arce nu este neaprat o matrice ptratic.

#Secvenele de citire a matricei vrfuri-arce:
int b[100][100];
.........................
cout<"n m ;
cin>>n>>m;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
{cout<<"b["<<i<<" ,<<j<<"]=";
cin>>b[i] [j];}
sau:
cout<<"n m ;
cin>>n>>m;
for (i=l;i<=m;i++)
{ cout<<"dati extremitatile arcului "<<i<<" "; cin>>x>>y;
b[x] [i]=1;
b[y][i]=-1;}
....................
2. Numrul elementelor egale cu l de pe linia i este egal cu gradul exterior al vrfului i:
int gr_ext_B( int i)
{int j, nr;
nr=0;
for (j=1;j<=m;j++)
if (b[i][j]==1) nr=nr+1;
return nr;}
3. Numrul elementelor egale cu -1 de pe linia i este egal cu gradul interior al vrfului i.
int gr_int_B( int i)
{int j, nr;
nr=0;
for (j=1;j<=m;j++)
if (b[i][j]==-1) nr=nr+1;
return nr;}
4. Dac vrful i este un vrf izolat, pe linia i nu sunt elemente egale cu 1 sau -1.
int vf_izolat_B( int i)
{return (gr_ext_B(i) ==0) && (gr_int_B(i)==0);}
13
5. Pe fiecare coloan j, exist un singur, element egal cu 1 i un singur element egal cu -1.
Indicele liniei pe care se afl 1 este extremitatea iniial a arcului u;
Indicele liniei pe care se afl -1 este extremitatea final a arcului u,

Construirea matricei de adiacen, cnd se cunoate matricea vfuri-arce.
- se parcurge matricea vrfuri-arce, de la prima pn la ultima coloan, cu j
- pe coloana j, se depisteaz indicele liniei pe care se afl 1. fie acesta plus l;
- pe coloana j, se depisteaz indicele liniei pe care se afl -I, fie acesta minus l;
- n matricea de adiacen elementul a[plus l, minus l] se face 1.
for (j=1 j<=m;j++)
{for (i=1;i<=n;i++)
if (b[i][j]==1) plusl=i;
else if (b[i][j]==-1) minusl=i;
a[plusl ][minusl]=1;}

Construirea matricei vrfuri-arce, cnd se cunoate matricea de adiacen.
- se folosete variabila ntreag k, cu urmtorul rol:
- reprezint numrul arcului la care s-a ajuns (la al ctelea element a
i,j
=1 s-a ajuns), care este practic indicele
curent al coloanei la care s-a ajuns n matricea vrfuri-arce.
- k=0;
- se parcurge matricea de adiacen, linie cu linie
- dac se gsete un element a
i,j
=1, atunci
- se mrete k cu 1;
- in coloana k, din matricea vrfuri-arce, se trece
pe linia i valoarea 1
pe linia j valoarea -1
.......................
k=0;
for (i=1;i<=n;i++)
for (j=1 j<=n;j++)
if (a[i][j]==1)
{k=k+1;
a[i][k]=1;
a[j][k]=-l;}
...........................

Matricea drumurilor

Fie G=(V, U) un graf orientat cu n vrfuri (V={ 1,2, ..., n}) i m arce.
Matricea drumurilor (DMn{0,1 })), asociat grafului G, este o matrice cu n linii i n coloane, cu
elementele:

=
j la i la de G in drum exista daca
j la i la de G in drum exista nu daca
d
j i
, 1
, 0
,


Exemplul 1.
Fie graful G=(V,U) : V={1,2,3,4}, U={(1,3),(2,3),(2,4),(4,1)} ={u
1
, u
2
, u
3
, u
4
},
reprezentat ca n figura de mai jos:
1

3


Matricea drumurilor asociat grafului este:
14
|
|
|
|
|

\
|
=
|
|
|
|
|

\
|
=
0 1 0 1
0 0 0 0
1 1 0 1
0 1 0 0
44 43 42 41
34 33 32 31
24 23 22 21
14 13 12 11
d d d d
d d d d
d d d d
d d d d
D

Exemplul 2.
Fie graful G : V={1,2,3,4},
U={(1,2),(1,4),(2,3),(3,1),(3,4),(4,2)}=
{u
1
, u
2
, u
3
, u
4
, u
5
, u
6
}
reprezentat ca n figura de mai jos:
1

3




Matricea drumurilor asociat grafului este:
|
|
|
|
|

\
|
=
|
|
|
|
|

\
|
=
0 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
44 43 42 41
34 33 32 31
24 23 22 21
14 13 12 11
d d d d
d d d d
d d d d
d d d d
D

Comentarii:
1. Matricea drumurilor este o matrice ptratic.
n continuare, este prezentat n pseudocod algoritmul Roy-Warshall de determinare a matricei drumurilor
plecnd de la matricea de adiacen. Algoritmul const ntr-un ir de transformri aplicate matricei de
adiacen. Vom spune c exist drum de la nodul i la nodul j, dac gsim un nod k cu proprietatea c exist
drum de la i la k i drum de la k la j. Astfel:
Un element ai,j care este 0 devine1, dac exist un nod k a.. a
i,k
=1 i a
k,j
=1. Pentru a gsi toate arcele
nodului k trebuie parcurse pe rnd n variabila k toate nodurile 1,2,.., n.
...............
pentru k=1 ... n
pentru i=1 ... n (i#k)
pentru j = 1 ... n (j#k)
dac a
i,j
=0 si i!=k si j!=k atunci
a
i,j
= a
ik
* a
kj

.....................

2. Dac n matricea drumurilor d
ii
=1, nseamn c exist n graf un circuit de extremiti i.
3. Dac n matricea drumurilor linia i i coloana i au elementele egale cu 0, nodul i este un nod izolat.

*Programul C/C++ de construire i afiare a matricei drumurilor.
#include <iostrearn.h>
#include <stdio.h>
#include <conio.h>
typedef int mat[30][30];
mat a;
int i, j, k, n, m, x, y;
void main()
{clrscr();
cout<<"n "; cin>>n;
cout<<"m="; cin>>m; secvena de citire a
for (i=1;i<=m;i++) matricei de adiacen
{cout<<"arcul "<<i<<" ";
cout<<" x y "; cin>>x>>y; a[x] [y]=1 ;}
for (k=1;k<=n;k++) secvena de transformare
for (i=1;i<=n;i++) a matricei de adiacen
for (j=1;j<=n;j++) in matricea drumurilor
15
if (a[i][j]==0)
a[i][j]=a[i][k] *a[k][j];
cout<<"matricea drumurilor este ";
for (i=1;i<=n;i++)
{for (j=1;j<=n;j++)
cout<<a[i] [j] " ";
cout<<endl;}
getch();}


Liste de adiacen

Fie G=(V, U) un graf orientat, cu n vrfuri (V={ 1,2, ..., n}) i m arce.
Reprezentarea grafului G, prin liste de adiacen, const n:
- precizarea numrului de vrfuri n;
- pentru fiecare vrf i, se precizeaz lista L; a succesorilor si, adic lista nodurilor care fac parte din
mulimea
+
(i).
Exemplul 1. Fie graful din figura de mai jos:
1

3
Reprezentarea sa, prin liste de adiacene,
presupune:
- precizarea numrului de vrfuri n, n=4;
- precizarea listei succesorilor lui i, pentru i=1..n
Vrful i Lista vecinilor lui i
1 3,4
2 3
3
4 2

Exemplul 2. Fie graful din figura de mai jos:
1


3
Reprezentarea sa, prin liste de adiacene,
presupune:
- precizarea numrului de vrfuri n, n=4;
- precizarea listei vecinilor lui i, pentru i=1..n
Vrful i Lista vecinilor lui i
1 2
2 4
3 1,2
4 1, 3

Comentarii:
Acest mod de reprezentare se poate implementa astfel:
1. Se folosete un tablou bidimensional, caracterizat astfel:
are n +m coloane;
T
1,i
=i, pentru i=1..n;
Pentru i=1..n T
2,i
= k, dac T
1,k
este primul nod din lista vecinilor lui i;
T
2,i
=0, dac nodul i nu are succesori;
Dac T
i,j
=u, adic u este un nod din lista vecinilor lui i, atunci:
T
2,j
=0, dac u este ultimul nod din lista vecinilor lui i;
T
2,j
=j+1, dac u nu este ultimul nod din lista vecinilor lui i.
Exemplu de completare a tabloului pentru graful de la exemplul 1.
Prima etap. Se numeroteaz coloanele (l..n+m), i se trec vrfurile.
1 2 3 4 5 6 7 8
1 2 3 4

A doua etap. Se trec n tabel vecinii lui 1, ncepnd de la coloana 5.
1 2 3 4 5 6 7 8
1 2 3 4 3 4
5 6 0
16
T
2,1
=5, pentru c primul vecin (3) al lui 1 s-a trecut la coloana 5 (T
1,5
=3);
T
2,5
=6, pentru c urmtorul vecin (4) al lui 1 s-a trecut la coloana 6 (T
1,
6=4);
T
2,6
=0, pentru c vecinul T
1,6
(4) al lui 1 este ultimul din list.
A treia etap. Se trec n tabel vecinii lui 2, ncepnd de la coloana 7.
1 2 3 4 5 6 7 8
1 2 3 4 3 4 3
5 7 6 0 0
T
2,2
=7, pentru c primul vecin (3) al lui 2 s-a trecut la coloana 7 (T
1,7
=3);
T
2,7
=0, pentru c vecinul T
1,7
(3) al lui 2 este ultimul din list.
A patra etap. Se trec n tabel vecinii lui 3, ncepnd de la coloana 8.
1 2 3 4 5 6 7 8
1 2 3 4 3 4 3
5 7 0 6 0 0
T
2,3
=0, pentru c 3 nu are succesori, deci lista sa este vid
Ultima etap. Se trec n tabel vecinii lui 4, ncepnd de la coloana 8 (aici s-a ajuns)
1 2 3 4 5 6 7 8
1 2 3 4 3 4 3 2
5 7 0 8 6 0 0 0
T
2,4
=8, pentru c primul vecin (2) al lui 4 s-a trecut la coloana 8 (T
1,8
= 2);
T
2,8
=0, pentru c vecinul T
1,8
(2) al lui 4 este ultimul din list.

2. Se folosete un tablou unidimensional, cu numele cap, i un tablou bidimensional, cu numele L (care
reine listele succesorilor pentru fiecare nod), caracterizate astfel:
Tabloul cap:
- are n componente;
- cap
i
= c, dac primul nod din lista vecinilor lui i este trecut n tabloul L la coloana c, adic L
1,c
este
primul vecin al lui i,
i cap
i
=0, dac nodul i nu are succesori.
Tabloul L:
- are m componente;
- dac k este un vecin al nodului i, atunci:
L
1,p
=k i L
2,p
=0, dac k este ultimul vecin din list, sau
L
1,p
=k i L
2,p
=p+1, dac k nu este ultimul vecin din list.
(p este coloana la care s-a ajuns n tabloul L)
Exemplu de completare a tablourilor cap i L, pentru graful de la exemplul l
Tabloul cap
1 2 3 4
1 3 0 4

Tabloul L
1 2 3 4
3 4 3 2
2 0 0 0

3. Se folosete un tablou bidimensional, cu numele L, caracterizat astfel:
- are n linii;
- pe linia i; se trec succesorii nodului i.
Exemplu de completare a tabloului L, pentru graful:
Tabloul L
3
1 4
2
1 3
17
Implementarea n limbajul C++, a ideii prezentate mai sus, se realizeaz conform secvenei de
program prezentat mai jos.
....................
int L[20][20];
int nr_vec[20];
cout<<"n="; cin>>n;
for (i=1;i<=n;i++)
{cout<<"Dati numarul vecinilor nodului "i; cinnr_vec[i];
for (j=1;j<=nr_vec[i];j++)
cin>>L[i][j];}
.........................
Construirea matricei de adiacen, cnd se cunoate L (listele vecinilor fiecrui nod).
..................
for (i=1;i<=n;i++)
{for (j=1;j<=nr_vec[i];j++)
a[i][L[i][j]]=1;}
...................
Construirea tabloului L (listele vecinilor nodurilor), cnd se cunoate matricea de adiacent
................
for (i=1; i<=n;i++)
{k=0;
for (j=1;j<=n;j++)
if (a[i][j]==1)
{k=k+1;
L[i][k]=j;}
}
................

4. Se folosete un tablou unidimensional, cu numele L, caracterizat astfel:
- componentele sale sunt de tip referin;
- are n componente;
- L
i
pointeaz spre nceputul listei succesorilor nodului i.

Construirea matricei de adiacen, cnd se cunoate L (listele vecinilor fiecrui nod).
....................
for (i=1;i<=n;i++)
{c=L[i];
while (c)
{a[i] [c->nod]=1;
c=c->urm;}
}
....................

irul arcelor

Fie G=(V, U) un graf orientat, cu n vrfuri (V={ 1,2, ..., n}) i m arce.
Reprezentarea grafului G const n precizarea numrului n de noduri i numrului m de arce precum i n
precizarea extremitilor pentru fiecare arc n parte.
Comentarii:
Acest mod de reprezentare se implementeaz astfel:
1. Se d numrul n de noduri i numrul m de arce, iar extremitile fiecrui arc sunt trecute n vectorii el si
e2, astfel:
- extremitile primului arc sunt el[1] i e2 [1];
- extremitile celui de-al doilea arc sunt e1[2] i e2[2];
.........................
18
- deci, U={( el[1],e2[1]) , (el[2],e2[2]) ,..., ( el [m],e2[m])}

Secvena C++corespunztoare este:
int el[100], e2[100];
int n, m, i;
cout<<"n="; cin>>n;
cout<<"m="; cin>>m;
for (i=1;i<=m;i++)
{cout<<"Dati extremitatile arcului cu numarul "<<i<<" ";
cin>>el[i]>>e2[i];}
..................
Construirea matricei de adiacen, cnd se cunoate irul muchiilor ca mai sus.
...................
cout<<"n="; cin>>n;
for (i=1;i<=m;i++)
a[el[i]] [e2[i]]=1;
.................
Construirea irului arcelor, ca mai sus, cnd se d matricea de adiacent.
................
k=0;
for (i=1;i<=n;i++)
for (j==1;j<=n;j++)
if (a[i][j] ==1)
{ k=k+1;
e1[k]=i;
e2[k]=j;}
m=k;
.................
2. Se folosete an tablou unidimensional, cu numele u, caracterizat astfel:
- componentele sale sunt de tip record;
- are m componente;
- u
i
reprezint arcul i.
Pentru implementare este nevoie de:
struct arc{int x;
int y;};
arc u[20];
......................
Accesul la arcul i se face: u[i].x ...... u[i].y
Secvena C++ corespunztoare este:
cout<<"n="; cin>>n;
cout<<"m "; cin>>m;
for (i=1;i<=m;i++)
{cout<<"'Dati extremitatile arcului cu numarul "<<i<< ;
cin>>u[i].x>>u[i].y;}
Construirea matricei de adiacent, cnd se cunoate irul arcelor ca mai sus:
.....................
cout<<"n='"; cin>>n;
for (i=1;i<=m;i++)
a[u[i].x][u[i].y]=1;
......................
Construirea irului arcelor, ca mai sus, cnd se d matricea de adiacen:
...............
k=0;
for (i=1; i<=n; i++)
for (j=1;j<=n;j++)
19
if (a[i][j]==1)
{ k=k+1;
u[k].x=i;
u[k].y =j;}
m=k;
..................

8. Graf tare conex. Componente tare conexe

n aceast seciune, vor fi prezentate noiunile:
- graf tare conex
- component tare conex
- algoritmul de descompunere a unui graf n componente tare conexe

Graf tare conex

Definiie. Fie G=(V, U) un graf orientat. Graful G se numete tare conex, dac pentru oricare dou vrfuri
x i y exist un drum n G de la x la y i un drum de la y la x.
Exemplu de graf tare conex.
1


Graful este tare conex, deoarece, oricare ar fi vrfurile x i y, exist un drum in G de la x la y i un drum de
la y la x.

Component tare conex

Definiie. Fie G=(V, U) un graf orientat. Se numete component tare conex, un graf orientat G
1
=(V
1
, U
1
)
care verific urmtoarele condiii:
- este subgraf al grafului G
- este tare conex;
- oricare are fi xV-V
1
, subgraful lui G generat de V
1
U{x} nu mai este tare conex .
Exemplu. Fie graful orientat prezentat n figura de mai jos:
1

3
Acest graf are dou componente tare conexe:
- subgraful generat de nodurile 1, 2, 3;
- subgraful generat de nodurile 4, 5, 6.
Observaie. Fie G=(V, U) un graf orientat: Graful G este tare conex, dac admite o singur component tare
conex.

Algoritmul de descompunere a unui graf n componente tare conexe

Algoritmul procedeaz astfel:
- la nceput, nu este depistat nici o component tare conex ( nc=0);
- deci, nici un nod nu face parte din vreo component tare conex (luate=[ ]);
- se parcurg nodurile grafului, cu i;
- dac i nu a fost introdus n nici o component tare conex,
20
- se mrete numrul componentelor tare conexe cu 1,
- se construiete noua component tare conex, astfel:
- se intersecteaz predecesorii lui i cu succesorii si, i se reunesc cu {i}.

Pentru implementarea acestui algoritm, n limbajul C++, cu ajutorul programului prezentat mai jos, s-au
folosit:
Funciile:
Succesori(i, S):care pune n irul S toate nodurile j, din graf , cu proprietatea c exist drum ntre i i ele.
Predecesori(i, P):care pune n irul P toate nodurile j, din graf, cu proprietatea c exist drum ntre ele i i.
Vectorul:
Comp :ale crui componente, care sunt iruri de elemente, vor reine, la final, componentele tare conexe;
Variabilele:
d : matricea drumurilor;
luate : un ir care reine toate nodurile care fac deja parte dintr-o component tare conex;
nc : reprezint numrul componentelor tare conexe depistate;
n program, au mai fost folosite i alte variabile dar deoarece rolul lor reiese foarte uor din urmrirea
programului nu-l mai comentm.

#include <iostream.h>
#include <conio.h>
#include <stdio.h>
typedef int mat[20][20];
typedef int sir[20];
mat d;
sir S, P, luate;
sir comp[50], ncomp;
int ok,nl, i, j, n, m, nc, ns, np;
void succesori(int i, sir S, int& ns)
{int j;
ns=0;
for (j=1;j<=n;j++)
if (d[i][j]==1)
{ns=ns+1;
S[ns]=j;}
}
void predecesori(int i, sir P, int& np)
{ int j;
np=0;
for (j=1;j<=n;j++)
if (d[j][i]==1)
{np=np+1;
P[np]=j;}
}
void intersectie(sir S, int ns, sir P, int np, sir x, int& nx)
{int ok;
int i, j;
nx=0;
for (i=1;i<=ns;i++ )
{ok=0;
for (j=1;j<=np;j++)
if (S[i]==P[j]) ok=1;
if (ok==1)
{nx++;
x[nx]=S[i];}
}
21
}
void main()
{clrscr();
cout<<"n="; cin>>n;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{cout<<"d["<<i<<","<<j<<"]";
cin>>d[i][j];}
nc=0;
nl=0;
for (i=1;i<=n;i++)
{ok=0;
for (j=1;j<=nl;j++)
if (luate[j]==i) ok=1;
if(ok==0)
{nc++;
succesori(i,S,ns);
predecesori(i,P,np);
intersectie(S,ns,P,np,comp[nc],ncomp[nc]);
for (j=1;j<=ncomp[nc];j++)
{nl++;
luate[nl]=comp[nc] [j];}
}
}
for (i=1;i<=nc;i++)
{cout<<"component tare conexa cu numarul "<<i<<endl;
for (j=1;j<=ncomp[i];j++)
cout<<comp[i][j]<<" ";
cout<<endl;}
getch();
}


9. Drumuri minime i maxime

Noiuni generale

n aceast seciune vor fi prezentate, aa cum sugereaz i titlul, modurile de tratare a problemelor care fac
parte din urmtoarele dou mari clase de probleme:
- probleme n care se cere determinarea drumurilor minime, dintr-un graf;
- probleme n care se cere determinarea drumurilor maxime, dintr-un graf.
Problemele de minim (maxim) se pot enuna astfel:
1. Fiind dat graful G=(V,U), cu matricea costurilor asociat CM
n
(R), s se determine drumurile de
lungime minim (maxim) ntre oricare dou vrfuri.
2. Fiind dat graful G=(V,U), cu matricea costurilor asociat CM
n
(R), s se determine drumurile de
lungime minim (maxim) ntre vrfurile i i j.
3. Fiind dat graful G=(V,U), cu matricea costurilor asociat CM
n
(R), s se determine drumurile de
lungime minim (maxim) ntre vrful i i toate celelalte vrfuri.
n cazul problemelor de minim, fiind dat graful G=(V, U) i se asociaz matricea costurilor, forma 1, definit
astfel:
CM
n
(R), unde:
22
( )


= =
U j i si j i daca
j i daca
t tul cu arc un exista j si i re daca t
c
j i
, ,
, 0
cos cos int , cos
,

n cazul problemelor de maxim, fiind dat graful G=(V, U) i se asociaz matricea costurilor, forma 2, definit
astfel:
CM
n
(R), unde:
( )


= =
U j i si j i daca
j i daca
t tul cu arc un exista j si i re daca t
c
j i
, ,
, 0
cos cos int , cos
,

Exemplu: Fiind dat graful din figura de mai jos (costul fiecrui arc fiind scris pe ea)
1 13
3
matricea costurilor se scrie in felul urmtor:
Forma 1:
|
|
|
|
|

\
|

=
|
|
|
|
|

\
|
=
0 14
0
12 15 0
13 11 0
44 43 42 41
34 33 32 31
24 23 22 21
14 13 12 11
c c c c
c c c c
c c c c
c c c c
C
Forma 2:
|
|
|
|
|

\
|




=
|
|
|
|
|

\
|
=
0 14
0
12 15 0
13 11 0
44 43 42 41
34 33 32 31
24 23 22 21
14 13 12 11
c c c c
c c c c
c c c c
c c c c
C
Observaii.
1. Matricea costurilor forma 1 difer de matricea costurilor forma 2 prin faptul c n loc de apare -.
2: n program nu se poate scrie sau -, de aceea recomandm ca atunci cnd trebuie folosite s se
defineasc dou constante foarte mari, ca de exemplu, pentru : const p infinit = 1.e10;
pentru - : const m infinit=-1.e10;
n continuare, vor fi prezentai doi algoritmi care permit rezolvarea unor probleme de minim (maxim), i
anume, vor fi prezentai:algoritmul Roy-Floyd i algoritmul lui Dijkstra..

Algoritmul Roy-Floyd

Acest algoritm se aplic n cazul problemelor n care se d un graf G=(V, U), care are matricea costurilor C,
i se cere s se determine lungimea drumurilor minime, i n unele cazuri i nodurile care constituie
drumurile respective, ntre oricare dou noduri ale grafului.
Observaie. Algoritmul are la baz urmtoarea idee:
"Dac drumul minim de la nodul i la nodul j trece prin nodul k, atunci i drumul de nodul i la
nodul k, precum i de la nodul k la nodul j, este minim"
i const, de fapt, ntr-un ir de n transformri aplicate matricei costurilor C, astfel:
T
k
(C)=B , BM
n
(R), b
i,j
=minim(c
i,j
,c
i,k
+c
k,j
),i,j {1,..n}care se poate implementa astfel:
for k=1 ... n
for i=1 ... n
for j=l ... n
if (c[i,j]<c[i,k]+c[k,j]) c[i,j]=c[i,k]+c[k,j];
23

Descrierea detaliat a algoritmului prezentat mai sus:
Pentru fiecare pereche de noduri (i,j), unde i,j { 1,...,n}, se procedeaz astfel:
se parcurg cu k toate nodurile grafului, diferite de i i j,
pentru fiecare nod k, se execut:
dac costul drumului ntre nodurile i i j este mai mic dect suma costurilor drumurilor
ntre nodurile i i k i ntre nodurile k i j, atunci costul drumului iniial de la i la j se va
nlocui cu costul drumului i-k-j, evident, acest lucru fcndu-se prin modificarea
matricei costurilor.
Observaie. Algoritmul prezentat n forma de mai sus, permite dect calcularea lungimii drumurilor minime
ntre oricare dou noduri ale grafului. Dac se dorete i afiarea nodurilor care compun efectiv aceste
drumuri, va trebui completat astfel:
Dac lungimea drumului miinim dintre nodurile i i j este egal cu suma dintre lungimile a 2 drumuri care
trec printr-un nod intremediar k atunci nodul k face parte din drumul de lungime minim de la i la j
#include<iostream.h>
#include<conio.h>
#include<fstream.h>
int a[50][50],n,i,j,c,k,gasit=0,x,y;
int const p_inf=10000;
ifstream f("rf.in");
void init() //se initializeaza matr costurilor
{f>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)if(i==j) a[i][j]=0;
else a[i][j]=p_inf;}
void citire()//se actualizeaza matr costurilor cu
datele din fisier
{while(f>>i>>j>>c) a[i][j]=c;
f.close();}
void transformare() //se transforma matricea
costurilor
{for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(a[i][k]+a[k][j]<a[i][j])
a[i][j]=a[i][k]+a[k][j];}
void drum(int i, int j) //se det nodurile drumului
minim
{for(k=1;k<=n&&!gasit;k++)
if((i!=k&&j!=k)&&a[i][j]==a[i][k]+a[k][j])
{drum(i,k);
drum(k,j);
gasit=1;}
if(!gasit) cout<<j<<" ";}
void afisare(int x,int y)//afiseaza costului de drum
minim si nodurile care formeaza drumul
{if(a[x][y]<p_inf)
{cout<<"drumul minim de la nodul "<<x<<" la nodul
"<<y;
cout<<" are costul "<<a[x][y]<<endl;
cout<<x<<" ";
drum(x,y);}
else cout<<"nu exista drum";}
void main()
{cout<<"x="; cin>>x;
cout<<"y="; cin>>y;
init();
citire();
transformare();
afisare(x,y);
getch();}

n continuare, se prezint programul, n C++, care implementeaz algoritmul comentat anterior

#include <iostream.h>
#include <conio.h>
#include <stdio.h>
const p_inf=10000;
typedef int sir[20];
typedef int mat[20][20];
typedef sir matmul[20][20];
matmul d;
mat c, nd;
sir dr;
int i, k, j, n,m, ld,x,y,val;
void drum_de_la(int i,int j)
{ int k, gasitk,t;
if (i!= j){
24
for (k=1;k<=n;k++)
{gasitk=0;
for (t=1;t<=nd[i][j];t++)
if (d[i][j][t]==k) gasitk=1;
if (gasitk==1)
{ ld=ld+1;
dr[ld]=k;
drum_de_la(i,k);
ld=ld-1;}
}
}
else{ for (k=ld;k>=1;k--) cout<<dr[k]<<" ";
cout<<endl;}
}
void afis()
{for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (c[i][j]==p_inf) cout<<"nu exista drum intre "<<i<<" si "<<j<<endl;
else if (i!=j)
{ cout<<"lung. drumului min de la "<<i<<" la "<<j<<" este "<<c[i][j]<<endl;
cout<<"iar drumurile sunt :"<<endl;
ld=1;
dr[ld]=j;
drum_de_la(i, j);}
}
void reuneste(sir x,int nx, sir y, int ny, sir z, int& nz)
{ int i, j, ok;
nz=0;
for (i=1;i<=nx;i++)
{nz++;
z[nz]=x[i];}
for (j=1;j<=ny;j++)
{ok=0;
for (i=1;i<=nx;i++)
if (x[i]==y[i]) ok=1;
if (!ok)
{nz++;
z[nz]=y[j];}
}
}
void face_sirul(sir x, int nx, sir y, int& ny)
{int i;
ny=0;
for (i=1;i<=nx;i++)
{ny++;
y[ny]=x[i]; }
}
void main()
{ clrscr();
cout<<"n="; cin>>n;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (i==j) c[i][j]=0;
else c[i][j]=p_inf;
cout<<"m="; cin>>m;
25
for (i=1;i<=m;i++)
{cout<<"x y val " ; cin>>x>>y>>val;
c[x][y]=val;}
for (i=1;i<=n;i++)
{for (j=1;j<=n;j++)
cout<<c[i][j]<<" ";
cout<<endl;}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if ((i!=j) && (c[i][j]<p_inf))
{ nd[i][j]=1;
d[i][j][1]=i;}
else nd[i][j]=0;
for (k=1;k<=n;k++)
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (c[i][j]==c[i][k]+c[k][j])
reuneste(d[i][j],nd[i][j],d[k][j],nd[k][j],d[i][j],nd[i][j]);
else if (c[i][j]>c[i][k]+c[k][j])
{ c[i][j]=c[i][k]+c[k][j];
face_sirul(d[k][j],nd[k][j],d[i][j],nd[i][j]);}
afis();
getche();}


Algoritmul lui Dijkstra

Acest algoritm se aplic n cazul problemelor n care se d un graf G=(V, U), care are matricea costurilor C,
i se cere s se determine lungimea drumurilor minime de la un nod dat x pn la fiecare nod din graf
Algortimul reine n mulimea S nodurile care au fost deja selectate i ntr-o coad de prioriti Q nodurile care nu au
fost deja selectate adic Q=V-S, astfel:
- un nod y este selectat atunci cnd s-a determinat costul final al drumului cu costul minim de la nodul sursa x
la el.
- - n coda Q prioritatea cea mai mare o are nodul pentru care costul drumului are valoarea cea mai mic dintre
toate costurile de drumuri care pornesc de la nodul x la celelalte noduri neselectate nc. Pentru calcularea
drumurilor de lungime minim se ntreine o mulime D n care se memoreaz costul drumurilor de la nodul x
la nodurile neselectate, costuri care se recalculeaz la fiecare extragere de nod.
Pas 1. Se iniializeaz mulimea S cu mulimea vid, se citete nodul iniial x i se atribuie mulimii S
Pas 2. Se iniiaz mulimea D cu costurile drumurilor de la nodul x la toate celelalte noduri ale grafului
Pas 3. Ct timp coada de prioriti Q nu este vid execut:
Pas 4. se caut printre nodurile selectate nodul y cu cel mai mic cost al drumului
Pas 5. se adaug nodul y la mulimea S (se extrage din coada de prioriti Q i se declar ca nod selectat)
Pas 6. Pentru fiecare nod neselectat execut:
Pas 7. Se recalculeaz costul drumului de la nodul x la acest nod folosind ca nod intermediar nodul
extras
Pas 8. Dac acest cost este mai mic dect cel din mulimea D, atunci el va fi noul cost.
Se folosesc 3 vectori:
- Vectorul s pentru mulimea nodurilor selectate
- Vectorul d conine costul drumurilor
- Vectorul t memoreaz drumurile gsite ntre nodul x i celelalte noduri i ale grafului
Algoritmul lui Dijkstra

Acest algoritm se aplic n cazul problemelor n care se d un graf G=(V, U), care are matricea costurilor C,
i se cere s se determine lungimea drumurilor minime de la un nod dat x pn la fiecare nod din graf
se selecteaz nodurile grafului unul cte unul n ordinea cresctoare a costului drumului de la nodul pl la ele, n
mulimea s, care iniial conine doar nodul pl.


26
A Al lg go or ri it tm mu ul l f fo ol lo os se e t te e u ur rm m t to oa ar re el le e v va ar ri ia ab bi il le e: :
n: reprezint numrul de noduri ale grafului;
c: reprezint matricea costurilor asociat grafului;
d - vect costului drumurilor
p-indic drumurile gsite ntre nodul pl i celelalte noduri din graf (pt nodul i se reine nodul precedent pe unde trece
drumul de la pl la i, pt pl se reine 0)
s- indic mulimea nodurilor selectate( 0 dac i nu este selectat, 1 dac i este selectat)

i i p pr ro oc ce ed de ea az z a as st tf fe el l: :
P Pa as s1 1. .- - s se e c ci it te e t te e n no od du ul l d de e p pl le ec ca ar re e p pl l; ;
- - s se e c co om mp pl le et te ea az z c co om mp po on ne en nt te el le e v ve ec ct to or ru ul lu ui i d d a as st tf fe el l
d d[ [i i] ]= =c c[ [p pl l, ,i i] ], , p pe en nt tr ru u i i= =1 1. .. .. .n n i i i i p pl l, ,
d d[ [p pl l] ]= =0 0
- - s se e c co om mp pl le et te ea az z c co om mp po on ne en nt te el le e v ve ec ct to or ru ul lu ui i p p a as st tf fe el l: :
p pe en nt tr ru u i i= =1 1. .: :: :n n, , p p[ [i i] ]= =p p1 1, , d da ac c i i p pl l i i c c[ [p pl l, ,i i] ] ; ;
p p[ [i i] ]= =0 0, , a al lt tf fe el l; ;
p pa as s2 2. . - - s se e e ex xe ec cu ut t d de e n n- -1 1 o or ri i u ur rm m t to oa ar re el le e: :
- - p pr ri in nt tr re e n no od du ur ri il le e n ne es se el le ec ct ta at te e s se e c ca au ut t c ce el l a af fl la at t l la a d di is st ta an n a a m mi in ni im m f fa a d de e p pl l i i s se e s se el le ec ct te ea az z , , a ad d u ug g n nd du u- -l l
m mu ul l i im mi ii i s s. . F Fi ie e p po oz z a ac ce es st t v v r rf f
- - p pe en nt tr ru u n no od du ur ri il le e n ne es se el le ec ct ta at te e, , j j, , s se e a ac ct tu ua al li iz ze ea az z n n d d c co os st tu ul l d dr ru um mu ur ri il lo or r d de e l la a p pl l l la a e el le e, , u ut ti il li iz z n nd d c ca a n no od d
i in nt te er rm me ed di ia ar r n no od du ul l s se el le ec ct ta at t, , p po oz z, , p pr ro oc ce ed d n nd d a as st tf fe el l: :
- -s se e c co om mp pa ar r c co os st tu ul l e ex xi is st te en nt t n n v ve ec ct to or ru ul l d d, , p pt t j j, , d d( (j j) ), , c cu u s su um ma a d di in nt tr re e c co os st tu ul l e ex xi is st te en nt t n n d d p pe en nt tr ru u n no od du ul l s se el le ec ct ta at t, ,
p po oz z, , i i d di is st ta an n a a d de e l la a n no od du ul l s se el le ec ct ta at t, , p po oz z, , l la a n no od du ul l p pe en nt tr ru u c ca ar re e s se e f fa ac ce e a ac ct tu ua al li iz za ar re ea a d di is st ta an n e ei i, , j j: :
d d( (p po oz z) ) a a( (p po oz z, ,j j) ) . . n n c ca az zu ul l n n c ca ar re e s su um ma a e es st te e m ma ai i m mi ic c , , e el le em me en nt tu ul l d di in n d d c co or re es sp pu un nz z t to or r n no od du ul lu ui i p pe en nt tr ru u c ca ar re e s se e
f fa ac ce e a ac ct tu ua al li iz za ar re ea a, , j j, , r re e i in ne e s su um ma a d d( (j j) ) d d( (p po oz z) ) + +a a( (p po oz z, ,j j) ) i i e el le em me et tu ul l d di in n p p c co or re es sp pu un nz z t to or r a ac ce el lu ua a i i v v r rf f, , i ia ar r
v va al lo oa ar re ea a v v r rf fu ul lu ui i s se el le ec ct ta at t p p( (j j) ) p po oz z ( (d dr ru um mu ul l t tr re ec ce e p pr ri in n a ac ce es st t v v r rf f) )
P Pa as s 3 3. . p pe en nt tr ru u f fi ie ec ca ar re e v v r rf f a al l g gr ra af fu ul lu ui i, , c cu u e ex xc ce ep p i ia a l lu ui i p pl l, , s se e t tr ra as se ea az z d dr ru um mu ul l d de e l la a p pl l l la a e el l. .

Exemplu de aplicare a algoritmului asupra grafului:
1

6


5

care are matricea costurilor:
|
|
|
|
|
|
|
|

\
|






=
0 3 2
0 1 3
0 1 3
2 0
4 0
2 2 0
C
Rezolvare:
Pasul 1
Se stabilete nodul de plecare: p1=1
Se completeaz vectorii d i p, astfel:
- d[i]=c[pl,i], pentru i=1...n;
(n componentele vectorului d se trec elementele de pe prima linie din C)
- pentru i=1...n, p[i]=p1, dac ipl i c[pl,i] ;
p[i]=0, altfel;

1 2 3 4 5 6
d 0 2 2
27
p 0 0 1 0 0 1

Pasul 2
Dintre nodurile nealese nc, nealese={2,3,4,5,6}, se alege nodul j pentru care d
j
=min{d
2
, d
3
, d
4
, d
5
, d
6
};
deci, se alege j=3, pentru ca d
3
=min{, 2, , , 2}

1 2 3 4 5 6
d 0 2
p 0 1

Se completeaz componentele vectorilor d i p, pentru nodurile nealese, astfel:
2 : min(d
2
, d
3
+C
3,2
)=min(,2+)= (d
2
i p
2
rmn nemodificate)
4 : min(d
4
, d
3
+C
3,4
)=min(,2+)= (d
4
i p
4
rmn nemodificate)
5 : min(d
5
, d
3
+C
3,5
)=min(,2+)= (d
5
i p
5
rmn nemodificate)
6 : min(d
6
, d
3
+C
3,6
)=min(2,2+2)=2 (d
5
i p
5
rmn nemodificate)

1 2 3 4 5 6
d 0 2 2
p 0 0 1 0 0 1

Pasul 3
Dintre nodurile nealese nc, nealese={2,4,5,6}, se alege nodul j pentru care d
j
=min{d
2
, d
4
, d
5
, d
6
}; deci, se
alege j=6, pentru c d
6
=min{, , , 2}

1 2 3 4 5 6
d 0 2 2
p 0 1 1

Se completeaz componentele vectorilor d i p, pentru nodurile nealese, astfel:
2 : min(d
2
, d
6
+C
6,2
)=min(,2+)= (d
2
i p
2
rmn nemodificate)
4 : min(d
4
, d
6
+C
6,4
) =min(,2+2)=4 (d
4
=4 i p
4
=6)
5 : min(d
5
, d
6
+C
6,5
)=min(,2+3)=5 (d
5
=5 i p
5
=6)
1 2 3 4 5 6
d 0 2 4 5 2
p 0 0 1 6 6 1

Pasul 4
Dintre nodurile nealese nc, nealese={2,4,5}, se alege nodul j pentru care d
j
=min{d
2
, d
4
, d
5
}; deci, se alege
j=4, pentru c d min{, 4, 5}

1 2 3 4 5 6
d 0 2 4 2
p 0 1 6 1
Se completeaz componentele vectorilor d i p, pentru nodurile nealese, astfel:
2 : min(d
2
, d
4
+C
4,2
)=min(,4+3)=7 (d
2
=7 i p
2
=4)
5 : min(d
5
, d
4
+C
4,5
)=min(5,4+)=5 (d
5
i p
5
rmn nemodificate)

1 2 3 4 5 6
d 0 7 2 4 5 2
p 0 4 1 6 6 1

Pasul 5
Dintre nodurile nealese nc, nealese={2,5}, se alege nodul j pentru care d
j
=min{d
2
, d
5
}; deci, se alege j=5,
pentru ca d
5
=min{, 5}.
28

1 2 3 4 5 6
d 0 2 4 5 2
p 0 1 6 6 1

Se completeaz componentele vectorilor d i p, pentru nodurile nealese, astfel:
2 : min(d
2
, d5+C
5,2
)=min(7,S+)=7 (d
2
i p
2
rmn nemodificate)

1 2 3 4 5 6
d 0 7 2 4 5 2
p 0 4 1 6 6 1

Concluzii:
Drumurile minime de la nodul 1 la celelalte noduri sunt:
2 : p
2
=4, p
4
=6, p
6
=1; deci, de la 1 la 2 avem : 1, 6, 4, 2
3 : p
3
=1; deci, de la 1 la 3 avem : 1, 3
4 : p
4
=6, p
6
=1; deci, de la 1 la 4 avem : 1, 6,4
5 : p
5
=6, p
6
=1; deci, de la 1 la 5 avem : 1, 6, 5
6.1 p
6
=1; deci, de la 1 la 6 avem : 1, 6



#include<iostream.h>
#include<conio.h>
#include<fstream.h>
ifstream f("d.in");
const p_inf=10000;
float a[50][50],d[50],min;
int n,i,j,pl,poz,p[50],s[50],c;
void drum (int i)
{if(p[i]!=0) drum(p[i]);
cout<<i<<" ";
}
void main()
{f>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i==j) a[i][j]=0;
else a[i][j]=p_inf;
while(f>>i>>j>>c)
a[i][j]=c;
f.close();
cout<<"pl="; cin>>pl;
for(i=1;i<=n;i++)
{d[i]=a[pl][i];
if(i!=pl&&d[i]<p_inf) p[i]=pl;}
for(i=1;i<=n-1;i++) {min=p_inf;
for(j=1;j<=n;j++)
if(s[j]==0)
if(d[j]<min)
{min=d[j];
poz=j;}
s[poz]=1;
for(j=1;j<=n;j++)
if(s[j]==0 && d[j]>d[poz]+a[poz][j])
29
{d[j]=d[poz]+a[poz][j];
p[j]=poz;}
}
for(i=1;i<=n;i++)
cout<<d[i]<<" ";
cout<<endl;
for(i=1;i<=n;i++)
if(i!=pl)
if(p[i]!=0)
{cout<<"drumul de cost minim de la nodul"<<pl<<" la nodul "<<i<<" are costul"<<d[i]<<endl;
cout<<endl;}
else
cout<<"Nu exista drum de la "<<pl<<" la "<<i<<endl;
getch();}


//algoritmul dijkstra
#include<iostream.h>
#include<conio.h>
#include<fstream.h>
int a[50][50],n,i,j,c,d[100],s[100],p[100],x,y,min;
int const p_inf=10000;
ifstream f("rf.in");
void init()//se initiealizeaza matr costurilor
{f>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)if(i==j) a[i][j]=0;
else a[i][j]=p_inf;}
void citire()//se actualizeaza matr costurilor cu datele din fisier
{while(f>>i>>j>>c) a[i][j]=c;
f.close();}
void generare_drum(int x) //se genereaza drumurile
{
s[x]=1;
for(i=1;i<=n;i++)
{d[i]=a[x][i];
if(i!=x &&d[i]<p_inf) p[i]=x;}
min=p_inf;
for(i=1;i<=n;i++)
{for(j=1;j<=n;j++)
if(s[j]==0&&d[j]<min)
{min=d[j];
y=j;}
s[y]=1;
for(j=1;j<=n;j++)
if(s[i]==0&&d[j]>d[y]+a[y][j])
{d[j]=d[y]+a[y][j];
p[j]=y;}
}}
void drum(int i)
{if (p[i]!=0) drum (p[i]);
cout<<i<<" ";}
void afisare(int x)
{for(i=1;i<=n;i++)
if(i!=x)
30
if(p[i]!=0)
{cout<<"drumul cu costul minim de la nodul "<<x;
cout<<" la nodul "<<i<<" are costul "<<d[i]<<endl;
drum(i);
cout<<endl;}
else cout<<" nu exista drum de la "<<x<<" la "<<i<<endl;}
void main()
{cout<<"x="; cin>>x;
init();
citire();
generare_drum(x);
afisare(x);
getch();}

You might also like