Documente Academic
Documente Profesional
Documente Cultură
Grafuri Orientate
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.
1
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 x V; 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 G1=(V, U1)
unde U1 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:
3
2. Un exemplu de graf parial al grafului G este
graful orientat:
reprezentat grafic astfel:
G1=(V, U) unde:
V={ 1,2,3,4}
U1=
(s-au eliminat toate arcele)
1
4
2
3
2
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 G1=(V1,U1)
unde V1 V iar U1 conine toate arcele din U care au extremitile n V1.
Exemplu: Fie graful orientat
G=(V, U) unde:
V={ 1,2,3,4}
U={(1,2), (2,3), (1,4)}
reprezentat grafic astfel:
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).
3
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:
+ (x ) = {y V ( x, y ) U }
2. Mulimea arcelor ce ies din x se noteaz cu +(x) i se reprezint astfel:
+ ( x ) = {( x, y ) U y V }
3. Legat de cardinalele mulimilor +(x) i +(x) putem scrie:
+ (x ) = + (x ) = d + (x )
Raportat la graful prezentat n figura de mai jos,
1
putem scrie:
+ (1)={2, 4} + (1)={(1,2), (1,4)} + (1) = + (1) = d + (1) = 2
+ (2)={1, 3} + (2)={(2,1), (2,3)} + (2) = + (2) = d + (2) = 2
+ (3)=
+ (3)=
+ (4)={4}
+ (4)=f (4,4)}
Grad interior
Definiie. Fie G=(V, U) un graf orientat i x un nod al su. Se numete grad interior al nodului x, num rul
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)}
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:
( x ) = {y V ( y, x ) U }
2. Mulimea arcelor ce intr in x se noteaz cu -(x) i se reprezint astfel:
( x ) = {( y, x ) U x V }
3. Legat de cardinalele mulimilor -(x) i -(x) putem scrie:
( x ) = ( x ) = d (x )
Raportat la graful prezentat n figura de mai jos,
1
4
putem scrie:
- (1)={2}
- (1)={(2,1)}
- (2)={1}
- (2)={(1,2)}
- (3)={2}
-(3) = {(2,3)}
- (4)={1,4} - (4)={(1,4),(4,4)}
i =1
i =1
d + (xi ) = d (xi ) = m
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).
n(n 1)
i n(n-1) arce. (U este privit ca o mulime
2
(d (x ) + d (x )) = (n 1) d (x ) + d (x ) = n(n 1)
+
i =1
i =1
i =1
(1)
i =1
i =1
i =1
d + (xi ) = d (xi ) = m
relaia (1) devine:
m + m = n(n 1) m =
n(n 1)
2
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
n(n 1)
2
= n(n 1)
2
n ( n 1)
6. Conexitate
comun cu arcul ui2 i extremitatea arcului uik care nu este comun cu arcul uik-1
- lungimea lanului
fiind dat lanul L = ui1 , ui 2 ,..., uik 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)}=
{ u1, u2, u3, u4, u5 }
1
Atenie! Dac L = ui1 , ui 2 ,..., ui k este lan n graful G, atunci i L1 = ui k , ui k 1 ,..., ui1 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
D = xi1 , xi 2 ,..., xik , cu proprietatea (xi1 , xi 2 ),..., xi k 1 , xi k U (altfel spus xi1 , xi 2 ,..., xi k 1 , xi k sunt arce).
) (
Se ntlnesc noiunile:
- extremitile drumului
fiind dat drumul D = xi1 , xi2 ,..., xik se numesc extremiti ale sale nodurile xi1 i xik (xi1 extremitate iniial
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:
Definiie. Fie G=(V,U) un graf orientat. Se numete drum elementar, n graful G, drumul
D = xi1 , xi2 ,..., xik cu proprietatea c oricare dou noduri ale sale sunt distincte (altfel spus, printr-un nod
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
D = xi1 , xi2 ,..., xik cu proprietatea c nodurile sale nu sunt distincte dou cte dou (altfel spus, prin anumite
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 D = xi1 , xi2 ,..., xik cu
proprietatea c xi1 = xik i are arcele cel compun diferite dou cte dou (circuitul se noteaz n continuare cu
C).
Exemplu: n graful de mai jos,
1
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 G1=(V1 ,U1) 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-V1.
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-V1={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):
9
Fie G=(V, U) un graf orientat, unde V={x1, x2,..., xn} i U={u1, u2,..., um} . Deoarece ntre mulimea {x1,
x2,..., xn} i mulimea {1, 2,..., n} exist o bijecie, xi 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 xi vom scrie i, i n loc de arcul (xi ,xj) 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 (A Mn({0,1})), asociat grafului G, este o matrice ptratic de ordin n, cu
elementele:
1, daca (i, j ) U
ai, j =
0, daca (i, j ) U
(altfel spus, ai,j=1, dac exist arc ntre i i j i ai,j=0 dac nu exist arc ntre i i j.
Exemplul 1.
Exemplul 2 .
Fie graful reprezentat ca n figura de mai jos:
Fie graful reprezentat ca n figura de mai jos:
1
1
2
3
Matricea de adiacen asociat grafului este:
a11 a12 a13 a14 0 0 1 0
a
1 0 0 0
a
a
a
41
42
43
44
2
3
Matricea de adiacen asociat grafului este:
a11 a12 a13 a14 0 1 0 1
0 1 0 0
a
a
a
a
41
42
43
44
* Comentarii:
l. Matricea de adiacen este o matrice ptratic, de ordin n, i nu este neap rat 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;
10
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)
3
Matricea vrfuri-arce asociat grafului este:
0
0 1
b11 b12 b13 b14 1
1
1
0
b21 b22 b23 b24 0
B=
=
b31 b32 b33 b34 1 1 0
0
b
0
b
b
b
0
1
1
41 42 43 44
11
3
Matricea vrfuri-arce asociat grafului este:
0 1 0 0
b11 b12 b13 b14 b15 b16 1 1
0 0 1
b21 b22 b23 b24 b25 b26 1 0 1
B=
=
b31 b32 b33 b34 b35 b36 0 0 1 1 1
0
b
41 b42 b43 b44 b45 b46 0 1 0 0 1 1
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);}
12
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 ai,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 ai,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 (D Mn{0,1 })), asociat grafului G, este o matrice cu n linii i n coloane, cu
elementele:
0, daca nu exista drum in G de la i la j
di , j =
1, daca exista drum in G de la i la j
Exemplul 1.
Fie graful G=(V,U) : V={1,2,3,4}, U={(1,3),(2,3),(2,4),(4,1)} ={u1, u 2, u 3, u4},
reprezentat ca n figura de mai jos:
1
Matricea drumurilor asociat grafului este:
3
13
d11 d12
d 22
d
D = 21
d
d 32
31
d
41 d 42
Exemplul 2.
Fie graful G : V={1,2,3,4},
U={(1,2),(1,4),(2,3),(3,1),(3,4),(4,2)}=
{u1, u2, u3, u4, u5, u6}
reprezentat ca n figura de mai jos:
1
d13
d 23
d 33
d 43
d14 0
d 24 1
=
d 34 0
d 44 1
0 1 0
0 1 1
0 0 0
0 1 0
d 21 d 22 d 23 d 24 1 1 1 1
=
D =
d
d 32 d 33 d 34 1 1 1 1
31
d
1 1 1 0
d
d
d
41
42
43
44
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.. ai,k=1 i ak,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 ai,j=0 si i!=k si j!=k atunci
ai,j= aik * akj
.....................
2.
3.
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 2. Fie graful din figura de mai jos:
Exemplul 1. Fie graful din figura de mai jos:
1
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
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;
T1,i=i, pentru i=1..n;
Pentru i=1..n T2,i= k, dac T1,k este primul nod din lista vecinilor lui i;
T2,i =0, dac nodul i nu are succesori;
Dac Ti,j=u, adic u este un nod din lista vecinilor lui i, atunci:
T2,j=0, dac u este ultimul nod din lista vecinilor lui i;
T2,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
15
T2,1=5, pentru c primul vecin (3) al lui 1 s-a trecut la coloana 5 (T1,5=3);
T2,5=6, pentru c urmtorul vecin (4) al lui 1 s-a trecut la coloana 6 (T1,6=4);
T2,6=0, pentru c vecinul T1,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
T2,2=7, pentru c primul vecin (3) al lui 2 s-a trecut la coloana 7 (T1,7=3);
T2,7=0, pentru c vecinul T1,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
T2,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
T2,4=8, pentru c primul vecin (2) al lui 4 s-a trecut la coloana 8 (T1,8= 2);
T2,8=0, pentru c vecinul T1,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;
- capi= c, dac primul nod din lista vecinilor lui i este trecut n tabloul L la coloana c, adic L1,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:
L1,p =k i L2,p=0, dac k este ultimul vecin din list, sau
L1,p=k i L2,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
3 4 3
2 0 0
4
2
0
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;
- Li 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:
- extremit ile primului arc sunt el[1] i e2 [1];
- extremitile celui de-al doilea arc sunt e1[2] i e2[2];
.........................
17
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
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 G1 =(V1, U1)
care verific urmtoarele condiii:
- este subgraf al grafului G
- este tare conex;
- oricare are fi x V-V1, subgraful lui G generat de V1U{x} nu mai este tare conex .
Exemplu. Fie graful orientat prezentat n figura de mai jos:
1
}
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();
}
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 C Mn(R), s se determine drumurile de
lungime minim (maxim) ntre oricare dou vrfuri.
2. Fiind dat graful G=(V,U), cu matricea costurilor asociat C Mn (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 C Mn (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:
C Mn (R), unde:
21
ci , j = 0, daca i = j
, daca i j si (i, j ) U
n cazul problemelor de maxim, fiind dat graful G=(V, U) i se asociaz matricea costurilor, forma 2, definit
astfel:
C Mn (R), unde:
cos t , daca int re i si j exista un arc cu cos tul cos t
ci , j = 0, daca i = j
, daca i j si (i, j ) U
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:
c11 c12 c13 c14 0 11 13
15 12
c21 c22 c23 c24 0
C =
=
c31 c32 c33 c34 0
c
14
c
c
c
0
41 42 43 44
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:
Tk(C)=B , B Mn (R), bi,j=minim(ci,j,ci,k+ck,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];
22
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;
24
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();}
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
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.
25
i procedeaz a stfel:
Pas1 .- se citete no du l de p lecare pl;
- se co mp leteaz co mponentele vecto rulu i d astfel
d [i]=c[pl,i], pentru i=1...n i ip l,
d [pl]=0
- se co mp leteaz co mponentele vecto rulu i p astfel:
p entru i=1 .::n, p[i]= p1, dac ip l i c[p l,i] ;
p[i]=0, altfel;
p as2. - se execut de n-1 o ri u rmto arele:
- printre no du rile neselectate se cau t cel aflat la distana minim fa de pl i se selecteaz, adugnd u-l
mu limii s. Fie p oz acest vrf
- pentru nodurile neselectate, j, se actualizeaz n d co stul dru mu rilo r de la p l la ele, u tiliznd ca nod
intermed iar no du l selectat, po z, pro ced nd astfel:
-se compar costu l existent n vecto ru l d, p t j, d(j), cu su ma dintre co stul existent n d p entru nodul selectat,
poz, i distana de la nodul selectat, poz, la nodul pentru care se face actu alizarea distanei, j:
d (po z)a(poz,j) . n cazul n care suma este mai mic, elementu l d in d corespunzto r nodu lu i pentru care se
face actu alizarea, j, reine suma d(j) d(poz) +a(poz,j) i elemetul din p corespunztor acelu ai vrf, iar
valoarea vrfulu i selectat p(j) poz (d rumul trece p rin acest vrf)
Pas 3. p entru fiecare vrf al grafului, cu excepia lui p l, se traseaz dru mul de la pl la el.
Exemplu de aplicare a algoritmului asupra grafului:
1
6
5
care are matricea costurilor:
0 2 2
0 4
0 2
C =
3 1 0
3 1 0
2 3 0
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
0
3
2
6
2
26
Pasul 2
Dintre nodurile nealese nc, nealese={2,3,4,5,6}, se alege nodul j pentru care dj=min{d 2, d3, d 4, d 5, d6};
deci, se alege j=3, pentru ca d3 =min{, 2, , , 2}
d
p
1
0
0
3
2
1
d
p
1
0
0
3
2
1
6
2
1
Pasul 3
Dintre nodurile nealese nc, nealese={2,4,5,6}, se alege nodul j pentru care dj=min{d2, d4, d5, d6}; deci, se
alege j=6, pentru c d6 =min{, , , 2}
d
p
1
0
0
3
2
1
6
2
1
1 2 3 4 5 6
2 4
2
d 0
1 6
1
p 0
Se completeaz componentele vectorilor d i p, pentru nodurile nealese, astfel:
2 : min(d2, d4+C4,2)=min(,4+3)=7 (d2 =7 i p 2 =4)
5 : min(d5, d4+C4,5)=min(5,4+)=5 (d5 i p5 rmn nemodificate)
d
p
1
0
0
2
7
4
3
2
1
4
4
6
5
5
6
6
2
1
Pasul 5
Dintre nodurile nealese nc, nealese={2,5}, se alege nodul j pentru care dj=min{d 2, d 5}; deci, se alege j=5,
pentru ca d5 =min{, 5}.
27
d
p
1
0
0
3
2
1
4
4
6
5
5
6
6
2
1
d
p
1
0
0
2
7
4
3
2
1
4
4
6
5
5
6
6
2
1
Concluzii:
Drumurile minime de la nodul 1 la celelalte noduri sunt:
2:
p2=4, p 4=6, p6=1; deci, de la 1 la 2 avem : 1, 6, 4, 2
3:
p3=1; deci, de la 1 la 3 avem : 1, 3
4:
p4 =6, p6 =1; deci, de la 1 la 4 avem : 1, 6,4
5:
p5=6, p 6=1; deci, de la 1 la 5 avem : 1, 6, 5
6.1
p6 =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])
28
{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)
29
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();}
30