P. 1
Grafuri+Orientate

Grafuri+Orientate

|Views: 50|Likes:
Published by Liana Popovici

More info:

Published by: Liana Popovici on Aug 21, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

08/21/2011

pdf

text

original

1

GRAFURI ORIENTATE


ASPECTE TEORETICE

1. NoŃiunea de graf orientat

DefiniŃie. Se numeşte graf orientat o pereche ordonată de mulŃimi notată G=(V, U), unde:
V : este o mulŃime, finită şi nevidă, ale cărei elemente se numesc noduri sau vârfuri;
U : este o mulŃime, de perechi ordonate de elemente distincte din V, ale cărei elemente se numesc arce.
• Exemplu de graf orientat:
G=(V, U) unde: V={ 1,2,3,4}
U={{1,2}, {2,3},{1,4}}
DemonstraŃie:
Perechea G este graf orientat deoarece respectă întocmai definiŃia prezentată mai sus, adică:
V : este finită şi nevidă:
U : este o mulŃime de perechi ordonate de elemente din V.

În continuare, vom nota submulŃimea {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 întâlnesc frecvent noŃiunile:
- extremităŃile unui arc
• fiind dat arcul u=(x,y), se numesc extremităŃi ale sale nodurile x şi y;
x se numeşte extremitate iniŃială;
y se numeşte extremitate finală.
- vârfuri adiacente
• dacă într-un graf există arcul u=(x,y) (sau u=(y,x), sau amândouă), se spune despre nodurile x şi y că sunt
adiacente;
- incidenŃă
• dacă ul şi u2 sunt două arce ale aceluiaşi 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ă: aşa cum s-a reprezentat graful din exemplul anterior;
- reprezentare grafică : arcele sunt reprezentate prin săgeŃi 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 definiŃii

DefiniŃie. Se numeşte graf orientat o pereche ordonată de mulŃimi notată G=(V, U), unde:
V : este o mulŃime, finită şi nevidă, ale cărei elemente se numesc noduri sau vârfuri;
U : este o mulŃime, de perechi ordonate de elemente din V, ale cărei elemente se numesc arce.
2
Această definiŃie diferă de prima definiŃie prin faptul ca acum nu se mai spune despre extremităŃile unui arc
ca trebuie să fie distincte. În baza acestei definiŃii, 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


DefiniŃie. Se numeşte graf orientat o pereche ordonată de mulŃimi notată G=(V, U), unde:
V : este o mulŃime, finită şi nevidă, ale cărei elemente se numesc noduri sau vârfuri;
U : este o familie de perechi ordonate de elemente din V, numită familia de arce.
Această definiŃie 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


ObservaŃie. Dacă într-un graf orientat numărul arcelor identice nu depăşeşte numărul p, atunci se
numeşte p-graf.

2. NoŃiunea de graf parŃial

DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte graf parŃial, al grafului G, graful orientat G
1
=(V, U
1
)
unde U
1
⊆U.
• AtenŃie! Citind cu atenŃie definiŃia, de mai sus, tragem concluzia:
Un graf parŃial, al unui graf orientat G=(V, U), are aceeaşi mulŃime de vârfuri ca şi G, iar mulŃimea arcelor
este o submulŃime 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 parŃial 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 parŃial 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
ObservaŃie. Fie G=(V, U) un graf orientat. Un graf parŃial, al grafului G, se obŃine păstrând vârfurile şi
eliminând eventual nişte arce (se pot elimina şi toate arcele sau chiar nici unul).

3. NoŃiunea de subgraf

DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte subgraf, al grafului G, graful orientat G
1
=(V
1
,U
1
)
unde V
1
⊆V iar U
1
conŃine toate arcele din U care au extremităŃile î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


ObservaŃie. Fie G=(V, U) un graf orientat. Un subgraf, al grafului G, se obŃine ştergând eventual anumite
vârfuri şi odată cu acestea şi arcele care le admit ca extremitate (nu se pot şterge toate vârfurile deoarece
s-ar obŃine un graf cu mulŃimea vârfurilor vidă).

4. Gradul unui vârf

Având la bază ideea că "raportat la un vârf există arce care ies din acel vârf şi arce care intră în acel vârf”, au
luat naştere următoarele noŃiuni:
- grad exterior
- grad interior
care vor fi prezentate in continuare.

Grad exterior

DefiniŃie. Fie G=(V, U) un graf orientat si x un nod al său. Se numeşte grad exterior al nodului x, numărul
arcelor de forma (x,y) (adică numărul 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)).
ObservaŃii.
1. MulŃimea succesorilor lui x se notează cu Γ
+
(x) şi se reprezintă astfel:
( ) ( ) { } U y x V y x ∈ ∈ = Γ
+
,
2. MulŃimea arcelor ce ies din x se notează cu ω
+
(x) şi se reprezintă astfel:
( ) ( ) { } V y U y x x ∈ ∈ =
+
, ω
3. Legat de cardinalele mulŃimilor Γ
+
(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

DefiniŃie. Fie G=(V, U) un graf orientat şi x un nod al său. Se numeşte grad interior al nodului x, numărul
arcelor de forma (y,x) ( adică numărul 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).
ObservaŃii.
1. MulŃimea predecesorilor lui x se notează cu Γ
-
(x) şi se reprezintă astfel:
( ) ( ) { } U x y V y x ∈ ∈ = Γ

,
2. MulŃimea arcelor ce intră in x se notează cu ω
-
(x) şi se reprezintă astfel:
( ) ( ) { } V x U x y x ∈ ∈ =

, ω
3. Legat de cardinalele mulŃimilor Γ
-
(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 ω

ObservaŃie. Un nod se numeşte izolat dacă:
d
+
(x)=d
-
(x)=0
PropoziŃie. Î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

DefiniŃie. Fie G=(V, U) un graf orientat. Graful G se numeşte graf complet dacă oricare două vârfuri
distincte ale sale sunt adiacente.
Două vârfuri 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

PropoziŃie. Într-un graf complet cu n vârfuri, există între
2
) 1 ( − n n
şi n(n-1) arce. (U este privită ca o mulŃime
(prima definiŃie a grafului) nu ca o familie)

DemonstraŃie: Numărul cel mai mic de arce, când graful este complet, se obŃine atunci când nodurile sunt
unite doar printr-un singur arc şi se determină astfel:
Pentru fiecare vârf x
i
, numărul arcelor care intră şi ies este n-1, deci d
+
(x
i
)+ d
-
(x
i
)=n-1, pentru orice i=1..n.
Însumând toate aceste relaŃii, obŃinem:
( ) ( ) ( ) ( ) ( ) ( ) ) 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)
łinând cont de faptul că:
( ) ( ) m x d x d
n
i
i
n
i
i
= =
∑ ∑
=

=
+
1 1

relaŃia (1) devine:

( )
2
1
) 1 (

= ⇒ − = +
n n
m n n m m
6
Numărul cel mai mare de arce, când graful este complet, se obŃine atunci când 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.
DefiniŃie Un graf orientat este turneu, dacă oricare ar fi 2 vârfuri i şi j, i≠j, între ele există un singur arc:
arcul(i,j) sau arcul (j,i)
ProprietăŃi:
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 vârfurile grafului.

Problemă. Fiind dat un graf turneu, se cere să se afişeze un drum elementar care trece prin toate vârfurile.
#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ă secŃiune, vor fi prezentate noŃiunile:
- lanŃ
- drum
- circuit
- graf conex
- componentă conexă

LanŃ

DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte 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 întâlnesc noŃiunile:
- extremităŃile lanŃului
• fiind dat lanŃul [ ]
k
i i i
u u u L ,..., ,
2 1
= se numesc extremităŃi 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 lanŃului
• fiind dat lanŃul [ ]
k
i i i
u u u L ,..., ,
2 1
= prin lungimea sa se înŃelege numărul 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 extremităŃile 1 şi 5.
L2=[ u
1
,u
2
, u
4
, u
5
] este, în graful G, lanŃ cu lungimea 4 şi extremităŃile 3 şi 5.

AtenŃie! 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

DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte 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 întâlnesc noŃiunile:
- extremităŃile drumului
• fiind dat drumul ( )
k
i i i
x x x D ,..., ,
2 1
= se numesc extremităŃi ale sale nodurile x
i1
şi x
ik
(x
i1
extremitate iniŃială

şi x
ik
extremitate finală)
- lungimea drumului
• fiind dat drumul ( )
k
i i i
x x x D ,..., ,
2 1
= , prin lungimea sa se înŃelege numărul de arce care apar în cadrul
său;
• 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 extremităŃile 1 şi 2.
D2=(4, 1, 3, 2) este, în graful G, drum cu lungimea 3 şi extremităŃile 4 şi 2.
AtenŃie! Dacă ( )
k
i i i
x x x D ,..., ,
2 1
= este drum, în graful G, atunci nu neapărat şi ( )
1
,..., , 1
1 i ik i
x x x D
k

= este drum,
în graful G.

DefiniŃie. Fie G=(V,U) un graf orientat. Se numeşte 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 decât o singură dată).
• Exemplu: în graful de mai jos,
1

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

DefiniŃie. Fie G=(V, U) un graf orientat: Se numeşte 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ă câte 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

DefiniŃie: Fie G=(V, I) un graf neorientat. Se numeşte 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ă câte 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.
DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte circuit elementar, în graful G, un circuit cu
proprietatea că oricare două noduri ale sale, cu excepŃia 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
DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte circuit neelementar, în graful G, un circuit cu
proprietatea că nodurile sale, cu excepŃia 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

DefiniŃie. Fie G=(V, U) un graf orientat. Graful G se numeşte conex dacă pentru oricare două vârfuri x şi y,
x#y, există un lanŃ de extremităŃi x şi y.
• Exemplu de graf care este conex:

3
Graful este conex, deoarece oricare ar fi vârfurile 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ă vârfuri, cum ar fi 1 şi 4, pentru care nu există nici un lanŃ în graf
care să le lege.

Componentă conexă

DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte componentă conexă un graf orientat G
1
=(V
1
,U
1
) care
verifică următoarele condiŃii:
- 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.
ObservaŃie. 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 mulŃimea {x
1
,
x
2
,..., x
n
} şi mulŃimea {1, 2,..., n} există o bijecŃie, x
i
↔i, putem presupune, fără a restrânge generalitatea,
mai ales pentru a uşura 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 întâi să fie reprezentat în
programul respectiv.
Pentru a reprezenta un graf orientat, într-un program, există mai multe modalităŃi folosind diverse structuri
de date; dintre acestea în continuare vom prezenta:
- reprezentarea prin matricea de adiacenŃă;
- reprezentarea prin matricea vârfuri-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 vârfuri (V={ 1,2, ..., n}) şi m arce.
Matricea de adiacenŃă (A∈M
n
({0,1})), asociată grafului G, este o matrice pătratică 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 pătratică, de ordin n, şi nu este neapărat simetrică faŃă de diagonala
principală, aşa cum este în cazul grafurilor neorientate.
SecvenŃele 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<<”]=”; cin»a[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 definiŃia 1,
când graful nu are bucle).

3. Numărul elementelor egale cu 1 de pe linia i este egal cu gradul exterior al vârfului 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. Numărul elementelor egale cu 1 de pe coloana i este egal cu gradul interior al vârfului 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ă vârful i este un vârf 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 vârfuri-arce ( matricea de incidenŃă)

Fie G=(V, U) un graf orientat cu n vârfuri (V={1,2, ..., n}) şi m arce.
Matricea vârfuri-arce (B∈M
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 vârfuri-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 vârfuri-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 vârfuri-arce nu este neapărat o matrice pătratică.

#SecvenŃele de citire a matricei vârfuri-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. Numărul elementelor egale cu l de pe linia i este egal cu gradul exterior al vârfului 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. Numărul elementelor egale cu -1 de pe linia i este egal cu gradul interior al vârfului 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ă vârful i este un vârf 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 iniŃială a arcului u;
Indicele liniei pe care se află -1 este extremitatea finală a arcului u,

• Construirea matricei de adiacenŃă, când se cunoaşte matricea vâfuri-arce.
- se parcurge matricea vârfuri-arce, de la prima până 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 vârfuri-arce, când se cunoaşte matricea de adiacenŃă.
- se foloseşte variabila întreagă k, cu următorul rol:
- reprezintă numărul arcului la care s-a ajuns (la al câtelea element a
i,j
=1 s-a ajuns), care este practic indicele
curent al coloanei la care s-a ajuns în matricea vârfuri-arce.
- k=0;
- se parcurge matricea de adiacenŃă, linie cu linie
- dacă se găseşte un element a
i,j
=1, atunci
- se măreşte k cu 1;
- in coloana k, din matricea vârfuri-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 vârfuri (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:
¦
¹
¦
´
¦
=
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 pătratică.
În continuare, este prezentat în pseudocod algoritmul Roy-Warshall de determinare a matricei drumurilor
plecând de la matricea de adiacenŃă. Algoritmul constă într-un şir de transformări aplicate matricei de
adiacenŃă. Vom spune că există drum de la nodul i la nodul j, dacă găsim 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 găsi toate arcele
nodului k trebuie parcurse pe rând î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 extremităŃi 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 afişare 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; secvenŃa 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++) secvenŃa 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 vârfuri (V={ 1,2, ..., n}) şi m arce.
Reprezentarea grafului G, prin liste de adiacenŃă, constă în:
- precizarea numărului de vârfuri n;
- pentru fiecare vârf i, se precizează lista L; a succesorilor săi, adică lista nodurilor care fac parte din
mulŃimea Г
+
(i).
• Exemplul 1. Fie graful din figura de mai jos:
1

3
Reprezentarea sa, prin liste de adiacenŃe,
presupune:
- precizarea numărului de vârfuri n, n=4;
- precizarea listei succesorilor lui i, pentru i=1..n
Vârful 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 adiacenŃe,
presupune:
- precizarea numărului de vârfuri n, n=4;
- precizarea listei vecinilor lui i, pentru i=1..n
Vârful 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 foloseşte 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 vârfurile.
1 2 3 4 5 6 7 8
1 2 3 4

A doua etapă. Se trec în tabel vecinii lui 1, începând 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ă următorul 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, începând 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, începând 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, începând 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 foloseşte un tablou unidimensional, cu numele cap, şi un tablou bidimensional, cu numele L (care
reŃine 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 foloseşte 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 secvenŃei 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; cin»nr_vec[i];
for (j=1;j<=nr_vec[i];j++)
cin>>L[i][j];}
.........................
• Construirea matricei de adiacenŃă, când se cunoaşte L (listele vecinilor fiecărui 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), când se cunoaşte 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 foloseşte 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Ńă, când se cunoaşte L (listele vecinilor fiecărui 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 vârfuri (V={ 1,2, ..., n}) şi m arce.
Reprezentarea grafului G constă în precizarea numărului n de noduri şi numărului m de arce precum şi în
precizarea extremităŃilor pentru fiecare arc în parte.
• Comentarii:
Acest mod de reprezentare se implementează astfel:
1. Se dă numărul n de noduri şi numărul m de arce, iar extremităŃile fiecărui arc sunt trecute în vectorii el si
e2, astfel:
- extremităŃile primului arc sunt el[1] şi e2 [1];
- extremităŃile 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])}

• SecvenŃa C++corespunzătoare 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Ńă, când se cunoaşte ş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, când 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 foloseşte 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
• SecvenŃa C++ corespunzătoare 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ă, când se cunoaşte ş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, când 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ă secŃiune, vor fi prezentate noŃiunile:
- graf tare conex
- componentă tare conexă
- algoritmul de descompunere a unui graf în componente tare conexe

Graf tare conex

DefiniŃie. Fie G=(V, U) un graf orientat. Graful G se numeşte tare conex, dacă pentru oricare două vârfuri
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 vârfurile x şi y, există un drum in G de la x la y şi un drum de
la y la x.

Componentă tare conexă

DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte componentă tare conexă, un graf orientat G
1
=(V
1
, U
1
)
care verifică următoarele condiŃii:
- este subgraf al grafului G
- este tare conex;
- oricare are fi x∈V-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.
ObservaŃie. 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 măreşte numărul componentelor tare conexe cu 1,
- se construieşte noua componentă tare conexă, astfel:
- se intersectează predecesorii lui i cu succesorii săi, şi se reunesc cu {i}.

Pentru implementarea acestui algoritm, în limbajul C++, cu ajutorul programului prezentat mai jos, s-au
folosit:
FuncŃiile:
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 cărui componente, care sunt şiruri de elemente, vor reŃine, la final, componentele tare conexe;
Variabilele:
d : matricea drumurilor;
luate : un şir care reŃine toate nodurile care fac deja parte dintr-o componentă tare conexă;
nc : reprezintă numărul componentelor tare conexe depistate;
În program, au mai fost folosite şi alte variabile dar deoarece rolul lor reiese foarte uşor din urmărirea
programului nu-l mai comentăm.

#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

NoŃiuni generale

În această secŃiune vor fi prezentate, aşa cum sugerează şi titlul, modurile de tratare a problemelor care fac
parte din următoarele 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 enunŃa astfel:
1. Fiind dat graful G=(V,U), cu matricea costurilor asociată C∈M
n
(R), să se determine drumurile de
lungime minimă (maximă) între oricare două vârfuri.
2. Fiind dat graful G=(V,U), cu matricea costurilor asociată C∈M
n
(R), să se determine drumurile de
lungime minimă (maximă) între vârfurile i şi j.
3. Fiind dat graful G=(V,U), cu matricea costurilor asociată C∈M
n
(R), să se determine drumurile de
lungime minimă (maximă) între vârful i şi toate celelalte vârfuri.
În cazul problemelor de minim, fiind dat graful G=(V, U) i se asociază matricea costurilor, forma 1, definită
astfel:
C∈M
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:
C∈M
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 fiecărui arc fiind scris pe ea)
1 13
3
matricea costurilor se scrie in felul următor:
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
ObservaŃii.
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 recomandăm ca atunci când 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 prezentaŃi doi algoritmi care permit rezolvarea unor probleme de minim (maxim), şi
anume, vor fi prezentaŃi: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.
ObservaŃie. Algoritmul are la bază următoarea 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 transformări aplicate matricei costurilor C, astfel:
T
k
(C)=B , B∈M
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 decât suma costurilor drumurilor
între nodurile i şi k şi între nodurile k şi j, atunci costul drumului iniŃial de la i la j se va
înlocui cu costul drumului i-k-j, evident, acest lucru făcându-se prin modificarea
matricei costurilor.
ObservaŃie. Algoritmul prezentat în forma de mai sus, permite decât calcularea lungimii drumurilor minime
între oricare două noduri ale grafului. Dacă se doreşte şi afişarea 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 până la fiecare nod din graf
Algortimul reŃine în mulŃimea S nodurile care au fost deja selectate şi într-o coadă de priorităŃi Q nodurile care nu au
fost deja selectate adică Q=V-S, astfel:
- un nod y este selectat atunci când 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 întreŃine o mulŃime 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 iniŃializează mulŃimea S cu mulŃimea vidă, se citeşte nodul iniŃial x şi se atribuie mulŃimii S
Pas 2. Se iniŃiază mulŃimea D cu costurile drumurilor de la nodul x la toate celelalte noduri ale grafului
Pas 3. Cât timp coada de priorităŃi 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 mulŃimea S (se extrage din coada de priorităŃi 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 decât cel din mulŃimea D, atunci el va fi noul cost.
Se folosesc 3 vectori:
- Vectorul s pentru mulŃimea nodurilor selectate
- Vectorul d conŃine costul drumurilor
- Vectorul t memorează drumurile găsite î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 până la fiecare nod din graf
se selectează nodurile grafului unul câte unul în ordinea crescătoare a costului drumului de la nodul pl la ele, în
mulŃimea s, care iniŃial conŃine 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ă numărul de noduri ale grafului;
c: reprezintă matricea costurilor asociată grafului;
d - vect costului drumurilor
p-indică drumurile găsite între nodul pl şi celelalte noduri din graf (pt nodul i se reŃine nodul precedent pe unde trece
drumul de la pl la i, pt pl se reŃine 0)
s- indică mulŃimea 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 stabileşte 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ă i≠pl ş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
rămân nemodificate)
4 : min(d
4
, d
3
+C
3,4
)=min(∞,2+∞)=∞ (d
4
şi p
4
rămân nemodificate)
5 : min(d
5
, d
3
+C
3,5
)=min(∞,2+∞)=∞ (d
5
şi p
5
rămân nemodificate)
6 : min(d
6
, d
3
+C
3,6
)=min(2,2+2)=2 (d
5
şi p
5
rămân 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
rămân 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
rămân 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
rămân 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();}

Această definiŃie diferă de prima definiŃie prin faptul ca acum nu se mai spune despre extremităŃile unui arc ca trebuie să fie distincte. În baza acestei definiŃii, 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

DefiniŃie. Se numeşte graf orientat o pereche ordonată de mulŃimi notată G=(V, U), unde: V : este o mulŃime, finită şi nevidă, ale cărei elemente se numesc noduri sau vârfuri; U : este o familie de perechi ordonate de elemente din V, numită familia de arce. Această definiŃie 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

ObservaŃie. Dacă într-un graf orientat numărul arcelor identice nu depăşeşte numărul p, atunci se numeşte p-graf. 2. NoŃiunea de graf parŃial DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte graf parŃial, al grafului G, graful orientat G1=(V, U1) unde U1 ⊆ U. • AtenŃie! Citind cu atenŃie definiŃia, de mai sus, tragem concluzia: Un graf parŃial, al unui graf orientat G=(V, U), are aceeaşi mulŃime de vârfuri ca şi G, iar mulŃimea arcelor este o submulŃime 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 parŃial al grafului G este graful orientat: G1=(V, U1) unde: V={ 1,2,3,4} U1={(1,2),(1,4)} (s-a eliminat arcul (2,3)) reprezentat grafic astfel: 1

3 2. Un exemplu de graf parŃial 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

ObservaŃie. Fie G=(V, U) un graf orientat. Un graf parŃial, al grafului G, se obŃine păstrând vârfurile şi eliminând eventual nişte arce (se pot elimina şi toate arcele sau chiar nici unul). 3. NoŃiunea de subgraf DefiniŃie. Fie G=(V, U) un graf orientat. Se numeşte subgraf, al grafului G, graful orientat G1=(V1,U1) unde V1 ⊆ V iar U1 conŃine toate arcele din U care au extremităŃile î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:

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

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

ObservaŃie. Fie G=(V, U) un graf orientat. Un subgraf, al grafului G, se obŃine ştergând eventual anumite vârfuri şi odată cu acestea şi arcele care le admit ca extremitate (nu se pot şterge toate vârfurile deoarece s-ar obŃine un graf cu mulŃimea vârfurilor vidă). 4. Gradul unui vârf Având la bază ideea că "raportat la un vârf există arce care ies din acel vârf şi arce care intră în acel vârf”, au luat naştere următoarele noŃiuni: - grad exterior - grad interior care vor fi prezentate in continuare. Grad exterior DefiniŃie. Fie G=(V, U) un graf orientat si x un nod al său. Se numeşte grad exterior al nodului x, numărul arcelor de forma (x,y) (adică numărul 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

2. Se numeşte grad interior al nodului x.4). (2.2). ObservaŃii. Gradul exterior al nodului 4 este d+(4)=1 (în graf. sunt două arce care intră în 4). U) un graf orientat şi x un nod al său. MulŃimea succesorilor lui x se notează cu Γ+(x) şi se reprezintă astfel: Γ + (x ) = {y ∈ V ( x. Legat de cardinalele mulŃimilor Γ-(x) şi ω-(x) putem scrie: Γ − ( x ) = ω − ( x ) = d − (x ) Raportat la graful prezentat în figura de mai jos. (2. MulŃimea predecesorilor lui x se notează cu Γ-(x) şi se reprezintă astfel: Γ − ( x ) = {y ∈ V ( y. ObservaŃii.4)} Γ + (1) = ω + (1) = d + (1) = 2 Γ+ (2)={1. MulŃimea arcelor ce intră in x se notează cu ω-(x) şi se reprezintă astfel: ω − ( x ) = {( y. numă rul arcelor de forma (y.4} U= {(1. U) unde: V={ 1.3)} Γ + (2) = ω + (2) = d + (2) = 2 Γ+ (3)= Ø Γ+ (4)={4} Grad interior DefiniŃie. (1.Gradul exterior al nodului 3 este d+(3)=0 (în graf.2). Gradul interior al nodului 4 este d-(4)=2 (în graf. • Exemplu: Fie graful orientat G=(V. Fie G=(V. (4.4)} Γ + (3) = ω + (3) = d + (3) = 0 Γ + (4) = ω + (4) = d + (4) = 1 reprezentat grafic astfel: Gradul interior al nodului 1 este d-(1)=1 (în graf.(2)=2 (în graf.x) ( adică numărul arcelor care intră in x). 1. notat d-(x). 1. 3} ω+ (2)={(2. Gradul interior al nodului 2 este d.3). x ) ∈ U x ∈ V } 3. este un arc care iese din 4 (bucla)). (1. MulŃimea arcelor ce ies din x se notează cu ω+(x) şi se reprezintă astfel: ω + ( x ) = {( x. nu sunt arce care ies din 3).2). y ) ∈ U } 2.1). este un arc care intră în 3). Legat de cardinalele mulŃimilor Γ+(x) şi ω+(x) putem scrie: Γ + (x ) = ω + (x ) = d + (x ) Raportat la graful prezentat în figura de mai jos. x ) ∈ U } 2.1). y ) ∈ U y ∈ V } 3. sunt două arce care intră în 2).4)} ω+ (3)= Ø ω+ (4)=f (4. 1 4 . (2. Gradul interior al nodului 3 este d-(3)=1 (în graf. 1 putem scrie: Γ+ (1)={2. (1. este un arc care intră în 1). 4} ω+ (1)={(1.3.

Un nod se numeşte izolat dacă: d+(x)=d-(x)=0 PropoziŃie.2).2)} ω-(3) = {(2.x). Într-un graf complet cu n vârfuri. obŃinem: ∑ (d (x ) + d (x )) = ∑ (n − 1) ⇒ ∑ d (x ) + ∑ d (x ) = n(n − 1) + − + − i i i i i =1 i =1 i =1 i =1 n n n n (1) łinând cont de faptul că: ∑ d + (xi ) = ∑ d − (xi ) = m i =1 i =1 n n relaŃia (1) devine: m + m = n(n − 1) ⇒ m = n(n − 1) 2 5 .(2)={(1...între ele există arcele (x.(3)={2} ω.putem scrie: Γ. U) un graf orientat.între ele există arcul (x.4} U={(1. în care V={x1.3)} Γ − (1) = ω − (1) = d − (1) = 1 Γ − (2) = ω − (2) = d − (2) = 1 Γ − (3) = ω − (3) = d − (3) = 1 Γ.între ele există arcul (y.4). sau .y) şi (y.4). Graf turneu DefiniŃie.(4. Graf complet. În graful orientat G=(V.4} ω. pentru orice i=1.xn} şi sunt m arce.3.n.4). (3.(4)={1. (2.(2)={1} Γ.1)} Γ.2. • Exemplu de graf orientat complet: G=(V. x2.. se verifică egalitatea : ∑ d + (xi ) = ∑ d − (xi ) = m i =1 i =1 n n 5.(1)={2} ω.y). U). (2. Însumând toate aceste relaŃii. când graful este complet. Fie G=(V.(4)={(1. sau .x). . U) unde: V={1.3).(1)={(2.(1.. numărul arcelor care intră şi ies este n-1. deci d+(xi)+ d-(xi)=n-1. Graful G se numeşte graf complet dacă oricare două vârfuri distincte ale sale sunt adiacente. (U este privită ca o mulŃime 2 (prima definiŃie a grafului) nu ca o familie) DemonstraŃie: Numărul cel mai mic de arce.3). Două vârfuri x şi y sunt adiacente dacă: .4)} Γ − (4) = ω − (4) = d − (4) = 2 ObservaŃie. (1. se obŃine atunci când nodurile sunt unite doar printr-un singur arc şi se determină astfel: Pentru fiecare vârf xi.4)} Reprezentarea sa grafică este: 1 PropoziŃie.. există între n(n − 1) şi n(n-1) arce.

j.} cout<<endl.j--) s[j+1]=s[j].p.i++) for(j=i+1. s[p]=k. şi este egal cu n(n − 1) 2 = n(n − 1) 2 n ( n −1) Lema Avem 3 2 grafuri complete cu n noduri.y) şi (y.L. între ele există un singur arc: arcul(i. Orice graf turneu este graf complet.} for(j=L. se obŃine atunci când nodurile sunt unite prin două arce. adică pentru nodurile x şi y există arcele (x. p=i+1. L++.k. dacă oricare ar fi 2 vârfuri i şi j.n.j.s[2]=1.} void generare_drum() {int i.i<=n.j) sau arcul (j.} L=2.Numărul cel mai mare de arce.a[20][20].j<=n.} void main() { cout<<"n=".h> int s[20].i. afisare_drum().k<=n."<<j<<")?[1/0]". când graful este complet. Avem 2 2 grafuri turneu cu n noduri 3. if(a[1][2]==1) {s[1]=1.} 6 . getch().q=0.j>=p. #include<iostream. cout<<endl. } while(!(a[i][j]==0 || a[i][j]==1)). În orice graf turneu există un drum elementar care trece prin toate vârfurile grafului.i) ProprietăŃi: 1.i++) 3 4 cout<<s[i]<<" ". do{ cin>>a[i][j]. for(i=1.s[2]=2. n ( n −1) 2.} else{s[1]=2. i≠j. a[j][i]=1-a[i][j].j++) {cout<<"exista arcul ("<<i<<". se cere să se afişeze un drum elementar care trece prin toate vârfurile. for(k=3. while(i<L&&!q) if(a[s[i]][k]==1&&a[k][s[i+1]]==1) q=1. for(i=1. Fiind dat un graf turneu. void afisare_drum() 2 1 {int i.} generare_drum().i<=n-1.h> #include<conio. else i++.k++) {if(a[k][s[1]]==1) p=1. Problemă .x).cin>>n.q. else{i=1. DefiniŃie Un graf orientat este turneu.

.4).3.. ui 2 .circuit . U) un graf orientat. lanŃ cu lungimea 3 şi extremităŃile 1 şi 5.2. vor fi prezentate noŃiunile: . xi k −1 . u3.2). uik cu proprietatea ca oricare două arce consecutive au o extremitate comună (nu are importanŃă orientarea arcelor). ui 2 . (5. U) unde: V={ 1.... ui 2 .. xi k −1 .u5] este..3). [ ] [ ] ( ) ( ) ( ) ( ) Se întâlnesc noŃiunile: . (4.. (2. xik se numesc extremităŃi ale sale nodurile xi1 şi xik (xi1 extremitate iniŃială ( ( ) ) şi xik extremitate finală) .5 } U={(1.4. xi k ∈ U (altfel spus xi1 .graf conex . AtenŃie! Dacă L = ui1 . xik . (5.lungimea lanŃului • fiind dat lanŃul L = ui1 .. prin lungimea sa se înŃelege numărul de arce care apar în cadrul său. xi 2 ...lungimea drumului • fiind dat drumul D = xi1 . uik se numesc extremităŃi ale sale extremitatea arcului ui1 care nu este [ ] [ [ ] ] comună cu arcul ui2 şi extremitatea arcului uik care nu este comună cu arcul uik-1 .extremităŃile lanŃului • fiind dat lanŃul L = ui1 ..3. L2=[ u1 . u5] este.lanŃ ..4).. notată D = xi1 .(1.. Fie G=(V. u4. xi k sunt arce). în graful G.. atunci şi L1 = ui k . xi 2 .5} U={(1.1).. uik prin lungimea sa se înŃelege numărul de arce care apar în L.. cu proprietatea (xi1 .u3 .6.extremităŃile drumului • fiind dat drumul D = xi1 ... ui 2 . (2. xik . lanŃ cu lungimea 4 şi extremităŃile 3 şi 5. Conexitate În această secŃiune... în graful G. unde: V={1. Se numeşte drum... o succesiune de arce. (3... U)..u2.... xi2 .4). în graful G.2)} cu reprezentarea grafică astfel: 7 .drum .. U) un graf orientat.. Se numeşte lanŃ. • Exemplu de drum: Fie graful G=(V. Fie G=(V. ui k −1 .. ui1 este lanŃ în graful G. u5 } 1 L1=[ u1 .. (2. în graful G. u2.2.. Drum DefiniŃie.2)}= { u1. o succesiune de noduri.componentă conexă LanŃ DefiniŃie.. notată L = ui1 .. • Exemplu de lanŃ: cu reprezentarea grafică astfel: Fie graful G=(V.. u4.. xi2 . xi 2 ).4.3).3). Se întâlnesc noŃiunile: . ui k este lanŃ în graful G..

3. atunci nu neapărat şi D1 = xik . 5. xik cu proprietatea că nodurile sale nu sunt distincte două câte două (altfel spus. Se numeşte drum elementar. Fie G=(V. Fie G=(V. 2) este. 1) este circuit.U) un graf orientat. în graful G.. • Exemplu: în graful de mai jos... prin anumite ( ) noduri s-a trecut de mai multe ori). xik este drum. xik cu proprietatea că oricare două noduri ale sale sunt distincte (altfel spus. 1 drumul D2=(4. xi2 .. în graful G. în graful G. cu excepŃia primului şi a ultimului. Se numeşte circuit elementar. 3.. drum cu lungimea 3 şi extremităŃile 4 şi 2. • Exemplu: în graful de mai jos. drumul D = xi1 . 4. Se numeşte circuit. xi1 este drum. 1. U) un graf orientat: Se numeşte drum neelementar.. 4.. I) un graf neorientat.. xik cu proprietatea că xi1 = xik şi are arcele cel compun diferite două câte două (circuitul se notează în continuare cu C). Fie G=(V. 2) este drum neelementar (prin 4 (şi 2) s-a trecut de două ori). 1 3 drumul D1=(4... în graful G. 1. 3. 2. printr-un nod ( ) nu se trece decât o singură dată ). D2=(4. • Exemplu: În graful de mai jos. în graful G. xi2 . 8 . xi2 . 2) este. DefiniŃie. în graful G. 4. 1 ( ) 3 drumul C=(1.. AtenŃie! Dacă D = xi1 . drumul D = xi1 .. în graful G. 2) este drum elementar. 3. sunt distincte. drum cu lungimea 2 şi extremităŃile 1 şi 2. DefiniŃie. • Exemplu: în graful de mai jos... U) un graf orientat.. drumul D = xi1 .. ( ) ( ) DefiniŃie. Circuit DefiniŃie: Fie G=(V. un circuit cu proprietatea că oricare două noduri ale sale. 3. xik −1 . 3.. 1. 2..D1=(1.. xi2 . 1 3 circuitul C=(1. în graful G. 1) este circuit elementar. 2..

nu există nici un lanŃ în G care să lege un nod din V. graful din figura de mai sus este format din două componente conexe.2).U2) unde: V2={1. există un lanŃ de extremităŃi x şi y. 5. ObservaŃie.2)} În concluzie. cu excepŃia primului şi a ultimului. Fie G=(V.este subgraf al grafului G. • Exemplu: în graful de mai jos 1 circuitul C=(1. x#y.5} şi U1={(4.U1) care verifică următoarele condiŃii: . U) un graf orientat. 1) este circuit neelementar (prin 4 s-a trecut de două ori). Fie G=(V. Se numeşte componentă conexă un graf orientat G1=(V1 . • Exemplu: Fie graful G=(V.1). .U1) unde: V1={4. 4. un circuit cu proprietatea că nodurile sale. Graful G este conex dacă şi numai dacă este format dintr-o singură componentă conexă. 4.2. Se numeşte circuit neelementar.2)> (3.5} şi U={(1.DefiniŃie. pentru care nu există nici un lanŃ în graf care să le lege. . U) un graf orientat.3) şi U2={(1.3.1). U) un graf orientat. (4. (3.5)} 1 2 Pentru graful de mai sus. există un lanŃ in G care să le lege. . Fie G=(V. Fie G=(V. Componentă conexă DefiniŃie. deoarece oricare ar fi vârfurile x şi y. (3. se poate spune şi despre graful G2=(V2. nu sunt distincte. graful G1=(V1.nu există nici un lanŃ în G care să lege un nod din V.4. în graful G. 3.2.este conex. • Exemplu de graf care este conex: 3 Graful este conex.5)} este componentă conexă. 2.este conex. cu an nod din V-V1. x#y. deoarece există două vârfuri.3} La fel. (3.2. deoarece: . • Exemplu de graf care nu este conex: 1 2 Graful nu este conex. Graf conex DefiniŃie. Graful G se numeşte conex dacă pentru oricare două vârfuri x şi y. cum ar fi 1 şi 4. cu un nod din V-V1={1. U) un graf orientat. U) : V={1. .este subgraf al grafului G. • Exemplu de graf conex (este format dintr-o singură componentă conexă): 9 .2).

şi nu este neap ărat simetrică faŃă de diagonala principală.. şi în loc de arcul (xi . în loc de xi vom scrie i. xn} şi mulŃimea {1. . asociată grafului G. • Exemplul 2 . Reprezentarea grafurilor orientate Fie G=(V.. ai. 10 .reprezentarea prin şirul arcelor. U) un graf orientat.j<=n.. . j ) ∈ U ai. Pentru a putea prelucra un graf orientat cu ajutorul unui program.i<=m. .. de ordin n. într-un program.} sau: cout<<"n m ” . Matricea de adiacenŃă este o matrice pătratică.i++) {cout«"dati extremitatile arcului "<<i<<" ”..j=1.reprezentarea prin matricea vârfuri-arce. um} .. cu elementele:  1. Pentru a reprezenta un graf orientat..”<<j<<”]=”. • Exemplul 1.. u2. SecvenŃele de citire a matricei de adiacenŃă: int a[100][100]. cin>>x>>y. n} există o bijecŃie.j). . U) un graf orientat cu n vârfuri (V={ 1.... aşa cum este în cazul grafurilor neorientate.. În baza celor spuse mai sus......2. 2.. cout<<"n=".reprezentarea prin listele de adiacenŃă. Matricea de adiacenŃă Fie G=(V. daca (i. că V={1.. Matricea de adiacenŃă (A∈ Mn({0.7.. x2.1})).. Deoarece între mulŃimea {x1.. x2. mai ales pentru a uşura scrierea. for (i=1.j++) {cout«"a[ "<<i<<”. cin>>n>>m.xj) vom scrie (i . cin»a[i][j]. cin>>n. trebuie mai întâi să fie reprezentat în programul respectiv.. for (i=1. n}) şi m arce.. 2. xi ↔i. xn} şi U={u1. unde V={x1. mai departe. există mai multe modalităŃi folosind diverse structuri de date. .reprezentarea prin matricea drumurilor.. dacă există arc între i şi j şi ai...i++) for (j=1..... fără a restrânge generalitatea.. dintre acestea în continuare vom prezenta: . este o matrice pătratică de ordin n.. j =  0.j=0 dacă nu există arc între i şi j.reprezentarea prin matricea de adiacenŃă. j ) ∉ U  (altfel spus.i<=n... . n}.... daca (i.. 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       a21 a22 a23 a24   0 0 1 1  A= = a a32 a33 a34   0 0 0 0   31    a a42 a43 a44   1 0 0 0   41    2 3 Matricea de adiacenŃă asociată grafului este:  a11 a12 a13 a14   0 1 0 1       a21 a22 a23 a24   0 0 1 0  A= = a a32 a33 a34   1 0 0 1   31    a a42 a43 a44   0 1 0 0   41    * Comentarii: l. putem presupune.

Numărul elementelor egale cu 1 de pe coloana i este egal cu gradul interior al vârfului i. Numărul elementelor egale cu 1 de pe linia i este egal cu gradul exterior al vârfului i.. return s..3). când graful nu are bucle). U={(1.. u2. s=0.. } Matricea vârfuri-arce ( matricea de incidenŃă) Fie G=(V.} . return s. asociată grafului G.2. daca i este extremitate finala pentru arcul u j   bi ...2... 3.U) : V={1. n}) şi m arce.j<=n.0. U) un graf orientat cu n vârfuri (V={1. este o matrice cu n linii şi m coloane. int gr int(int i) {int j.(2.3. Fie graful G=(V. cu elementele: − 1.. Matricea vârfuri-arce (B ∈ Mnxm({-1. Matricea de adiacenŃă are toate elementele de pe diagonala principală egale cu 0 (ne referim la definiŃia 1.a[x][y]=1. j = 0.(2.(4.1)}= {u1... u3. int gr_ext(int i) {int j ..3).j<=n.. int vf_izolat(int i) {return (gr_ext(i)==0) && (gr_int(i)==0).4}. s=0... daca i este extremitate initiala pentru arcul u j  • Exemplul 1.} 5.. s. for (j=1. .j++) s=s+a[j][i].j++) s=s+a[i][j].1})). for (j=1.. Dacă vârful i este un vârf izolat.} 4.. pe linia i şi coloana i nu sunt elemente egale cu 1.4). u4} reprezentat ca in figura de mai jos: 1 3 Matricea vârfuri-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 b42 b43 b44   0 0 −1 1   41    11 .. s.. daca i nu este extremiate pentru arcul u j  1.. 2..

cin>>b[i] [j].. cout<"n m” ...4).(1..2.} 4. u3. u2.. # SecvenŃele de citire a matricei vârfuri-arce: int b[100][100]..j++) if (b[i][j]==-1) nr=nr+1.. nr=0.i++) for (j=1.. nr..} sau: cout<<"n m” . nr......• Exemplul 2..j<=m.. reprezentat ca în figura de mai jos: 1 3 Matricea vârfuri-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....2)}= {u1..j<=m.. Numărul elementelor egale cu -1 de pe linia i este egal cu gradul interior al vârfului i. cin>>n>>m..(3.. U={(1..4). for (j=1. pe linia i nu sunt elemente egale cu 1 sau -1.3). int vf_izolat_B( int i) {return (gr_ext_B(i) ==0) && (gr_int_B(i)==0). Numărul elementelor egale cu l de pe linia i este egal cu gradul exterior al vârfului i: int gr_ext_B( int i) {int j..2).”<<j<<"]="... b[y][i]=-1.(3. u6}. for (i=l. Matricea vârfuri-arce nu este neapărat o matrice pătratică..u5.i<=m. u4. . for (i=1...} .} 12 .. int gr_int_B( int i) {int j. return nr.i++) { cout<<"dati extremitatile arcului "<<i<<" "..(2.} 3.3.. 2. return nr.. Fie graful G : V={ 1. cin>>x>>y..j<=m.. nr=0.j++) if (b[i][j]==1) nr=nr+1... b[x] [i]=1. cin>>n>>m.j++) {cout<<"b["<<i<<" ...1).. for (j=1. Dacă vârful i este un vârf izolat...4}.(4.i<=n.

.. else if (b[i][j]==-1) minusl=i... de la prima până la ultima coloană.dacă se găseşte un element ai.3)..1 })). a[plusl ][minusl]=1. . care este practic indicele curent al coloanei la care s-a ajuns în matricea vârfuri-arce. n}) şi m arce.. se depistează indicele liniei pe care se află -I.. când se cunoaşte matricea vâfuri-arce. a[i][k]=1.. daca nu exista drum in G de la i la j  di .j++) {for (i=1....pe coloana j. .. .} • Construirea matricei vârfuri-arce....j++) if (a[i][j]==1) {k=k+1.3. • Construirea matricei de adiacenŃă.. Matricea drumurilor (D∈ Mn{0...i++) if (b[i][j]==1) plusl=i.. a[j][k]=-l. cu elementele: 0. minus l] se face 1..U) : V={1.... există un singur. cu următorul rol: . ..în matricea de adiacenŃă elementul a[plus l..k=0. U={(1.. din matricea vârfuri-arce.i<=n.se parcurge matricea de adiacenŃă. când se cunoaşte matricea de adiacenŃă. Indicele liniei pe care se află -1 este extremitatea finală a arcului u.. . Pe fiecare coloană j.} .i<=n..se măreşte k cu 1. .(2. fie acesta plus l..i++) for (j=1 j<=n.. atunci .... u4}. u 3..se foloseşte variabila întreagă k.. for (i=1.3).2. este o matrice cu n linii şi n coloane. for (j=1 j<=m. Matricea drumurilor Fie G=(V. fie acesta minus l. ..... linie cu linie .2.. cu j .j=1..pe coloana j..(4.1)} ={u1..5. Indicele liniei pe care se află 1 este extremitatea iniŃială a arcului u.4). u 2.. U) un graf orientat cu n vârfuri (V={ 1. k=0. reprezentat ca în figura de mai jos: 1 Matricea drumurilor asociată grafului este: 3 13 . daca exista drum in G de la i la j  • Exemplul 1. Fie graful G=(V. j =  1.4}. se trece pe linia i valoarea 1 pe linia j valoarea -1 .se parcurge matricea vârfuri-arce.... se depistează indicele liniei pe care se află 1..(2... element egal cu 1 şi un singur element egal cu -1..j=1 s-a ajuns)..reprezintă numărul arcului la care s-a ajuns (la al câtelea element ai.in coloana k. asociată grafului G.

. 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  3 Matricea drumurilor asociată grafului este:  d11 d12 d13 d14  1 1 1 1       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 d 42 d 43 d 44  1 1 1 0   41    • Comentarii: 1. secvenŃa de citire a for (i=1.. Algoritmul constă într-un şir de transformări aplicate matricei de adiacenŃă.. Pentru a găsi toate arcele nodului k trebuie parcurse pe rând în variabila k toate nodurile 1. d11 d12  d 22 d D =  21 d d 32  31 d  41 d 42 • Exemplul 2.j++) in matricea drumurilor 14 .i<=m...j=0 si i!=k si j!=k atunci ai.j=1...h> typedef int mat[30][30].. 2... nodul i este un nod izolat.1)...2.. int i. n.i++) a matricei de adiacenŃă for (j=1. dacă găsim un nod k cu proprietatea că există drum de la i la k şi drum de la k la j..î... Dacă în matricea drumurilor dii=1.} for (k=1.i++) matricei de adiacenŃă {cout<<"arcul "<<i<<" ". u2.. cin>>x>>y. Vom spune că există drum de la nodul i la nodul j..2)}= {u1... *Programul C/C++ de construire şi afişare a matricei drumurilor. y.i<=n.. n (i#k) pentru j = 1 . u5. dacă există un nod k a. k. Matricea drumurilor este o matrice pătratică..k=1 şi ak. m.. void main() {clrscr(). n (j#k) dacă ai.k<=n.4).(3.. cout<<" x y ". În continuare.. .. pentru k=1 ... u4.. Dacă în matricea drumurilor linia i şi coloana i au elementele egale cu 0...(1.j care este 0 devine1. n pentru i=1 .3).4}. ai.(2.. cout<<"m=". U={(1. înseamnă că există în graf un circuit de extremităŃi i. 3.. u3. cin>>n...h> #include <stdio.... cin>>m.j= aik * akj . #include <iostrearn.. j.4). cout<<"n ".(3. Astfel: Un element ai.k++) secvenŃa de transformare for (i=1. x..2).2. Fie graful G : V={1..3.h> #include <conio.(4.j<=n. este prezentat în pseudocod algoritmul Roy-Warshall de determinare a matricei drumurilor plecând de la matricea de adiacenŃă. mat a. n.. a[x] [y]=1 ..

adică lista nodurilor care fac parte din mulŃimea Г+(i).if (a[i][j]==0) a[i][j]=a[i][k] *a[k][j]. constă în: .precizarea listei succesorilor lui i. dacă nodul i nu are succesori. Reprezentarea grafului G. pentru i=1. dacă u este ultimul nod din lista vecinilor lui i. 3 • Comentarii: Acest mod de reprezentare se poate implementa astfel: 1. presupune: .n. dacă u nu este ultimul nod din lista vecinilor lui i.. • Dacă Ti. • Pentru i=1. T2. 1 2 3 4 5 6 7 8 1 2 3 4 A doua etap ă.. prin liste de adiacenŃe. Fie graful din figura de mai jos: • Exemplul 1. U) un graf orientat.4 2 3 3 4 2 3 Reprezentarea sa..precizarea numărului de vârfuri n.j++) cout<<a[i] [j] « " ".. • T1. Fie graful din figura de mai jos: 1 1 3 Reprezentarea sa. adică u este un nod din lista vecinilor lui i. cout<<"matricea drumurilor este ".precizarea numărului de vârfuri n.i++) {for (j=1.precizarea numărului de vârfuri n.} Liste de adiacenŃă Fie G=(V.n Vârful i Lista vecinilor lui i 1 3. prin liste de adiacenŃă. • Exemplul 2. .n Vârful i Lista vecinilor lui i 1 2 2 4 3 1.j<=n.2. a succesorilor săi. .i= k. Prima etapă. cu n vârfuri (V={ 1. dacă T1.j=j+1. prin liste de adiacenŃe.n T2.i=i. presupune: . Se numerotează coloanele (l. pentru i=1.} getch(). pentru i=1. .i<=n.j=0.. Se trec în tabel vecinii lui 1.2 4 1.n+m).i =0. • Exemplu de completare a tabloului pentru graful de la exemplul 1..k este primul nod din lista vecinilor lui i.. cout<<endl. T2. . n=4. n}) şi m arce. şi se trec vârfurile. n=4. începând de la coloana 5. atunci: T2. for (i=1. 1 2 3 4 5 6 7 8 1 2 3 4 3 4 5 6 0 15 .j=u. Se foloseşte un tablou bidimensional.. caracterizat astfel: • are n +m coloane. se precizează lista L.precizarea listei vecinilor lui i.pentru fiecare vârf i.

4=8. Se trec în tabel vecinii lui 2. .1=5.are n linii. dacă primul nod din lista vecinilor lui i este trecut în tabloul L la coloana c.T2.5=6. cu numele L.2=7.7 (3) al lui 2 este ultimul din listă.p=k şi L2.6=0. Tabloul L: .capi= c. sau L1. caracterizate astfel: Tabloul cap: . (p este coloana la care s-a ajuns în tabloul L) • Exemplu de completare a tablourilor cap şi L. caracterizat astfel: . pentru că primul vecin (2) al lui 4 s-a trecut la coloana 8 (T1.p =k şi L2. pentru că primul vecin (3) al lui 2 s-a trecut la coloana 7 (T1.3=0. 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 3. Se foloseşte un tablou bidimensional.5=3). cu numele L (care reŃine listele succesorilor pentru fiecare nod). dacă nodul i nu are succesori.6=4).are n componente. 2. A patra etap ă. . atunci: L1.7=3). 1 2 3 4 5 6 7 8 1 2 3 4 3 4 3 5 7 0 6 0 0 T2. Se trec în tabel vecinii lui 4. pentru că vecinul T1. dacă k este ultimul vecin din listă. începând de la coloana 7. pentru că primul vecin (3) al lui 1 s-a trecut la coloana 5 (T1. pentru că vecinul T1. şi un tablou bidimensional.8 (2) al lui 4 este ultimul din listă.p=p+1. . T2. cu numele cap.p=0.c este primul vecin al lui i. se trec succesorii nodului i. • Exemplu de completare a tabloului L.pe linia i. pentru graful: Tabloul L 3 1 4 2 1 3 16 .6 (4) al lui 1 este ultimul din listă. dacă k nu este ultimul vecin din listă. Se foloseşte un tablou unidimensional. T2. deci lista sa este vid ă Ultima etapă.are m componente. pentru că 3 nu are succesori.8= 2). adică L1.dacă k este un vecin al nodului i. pentru că următorul vecin (4) al lui 1 s-a trecut la coloana 6 (T1. începând de la coloana 8. 1 2 3 4 5 6 7 8 1 2 3 4 3 4 3 5 7 6 0 0 T2. începând 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. şi cap i =0.7=0. A treia etapă. pentru că vecinul T1. T2. T2. Se trec în tabel vecinii lui 3.8=0.

. cu numele L.... U) un graf orientat. ..i++) {c=L[i].. cin>>n... while (c) {a[i] [c->nod]=1.i++) {k=0.. ..... când se cunoaşte L (listele vecinilor fiecărui nod)...are n componente.... n}) şi m arce.... • Comentarii: Acest mod de reprezentare se implementează astfel: 1.........componentele sale sunt de tip referinŃă..• Implementarea în limbajul C++...... • Construirea tabloului L (listele vecinilor nodurilor)....i<=n. .. Reprezentarea grafului G constă în precizarea numărului n de noduri şi numărului m de arce precum şi în precizarea extremităŃilor pentru fiecare arc în parte...j++) cin>>L[i][j]. ....} ..j++) a[i][L[i][j]]=1.........} } ... int L[20][20]....i++) {for (j=1.j<=nr_vec[i]. 4.. se realizează conform secvenŃei de program prezentată mai jos.2. • Construirea matricei de adiacenŃă.i<=n.. când se cunoaşte L (listele vecinilor fiecărui nod)......... .... for (i=1..... for (i=1....... for (j=1.....j<=n... ......... Se foloseşte un tablou unidimensional.. L[i][k]=j. i<=n... Se dă numărul n de noduri şi numărul m de arce.. for (i=1.. a ideii prezentate mai sus.} } .... astfel: ... cin»nr_vec[i]...Li pointează spre începutul listei succesorilor nodului i.......j++) if (a[i][j]==1) {k=k+1.......extremităŃ ile primului arc sunt el[1] şi e2 [1]......j<=nr_vec[i]. c=c->urm.} .. ...... cu n vârfuri (V={ 1.... iar extremităŃile fiecărui arc sunt trecute în vectorii el si e2. când se cunoaşte matricea de adiacentă ... 17 . caracterizat astfel: .. int nr_vec[20]. .... for (i=1................ cout<<"n="......extremităŃile celui de-al doilea arc sunt e1[2] şi e2[2]....i++) {cout<<"Dati numarul vecinilor nodului "«i.. Şirul arcelor Fie G=(V.... • Construirea matricei de adiacenŃă...i<=n.... for (j=1...

..i++) for (j==1.. • Construirea şirului arcelor.. • Pentru implementare este nevoie de: struct arc{int x.e2[2]) ....i<=m... cu numele u.. m..i<=n. for (i=1... for (i=1. cin>>n... cin>>u[i].. cin>>n..} • Construirea matricei de adiacentă.. arc u[20]. • Construirea şirului arcelor. for (i=1... caracterizat astfel: . for (i=1.. i... ... ca mai sus..... .....x . k=0... când se cunoaşte şirul arcelor ca mai sus: ......e2[1]) .i++) {cout<<"'Dati extremitatile arcului cu numarul "<<i<<” ”..i<=m. U={( el[1].j<=n.... e1[k]=i.. Accesul la arcul i se face: u[i].....y • SecvenŃa C++ corespunzătoare este: cout<<"n=". ( el [m]..} m=k... 2.. • Construirea matricei de adiacenŃă... când se dă matricea de adiacenŃă : ...y.x>>u[i].. ..i<=m... e2[k]=j... cin>>n..... când se cunoaşte şirul muchiilor ca mai sus...} . ... cout<<"n="......... cout<<"m ".i++) a[u[i].. . e2[100]... cout<<"n=".. for (i=1.i++) {cout<<"Dati extremitatile arcului cu numarul "<<i<<" ".. cin>>n.... cin>>m................e2[m])} • SecvenŃa C++corespunzătoare este: int el[100]... (el[2]. i<=n...deci. for (i=1..j++) 18 .i++) a[el[i]] [e2[i]]=1.componentele sale sunt de tip record... ca mai sus. când se dă matricea de adiacentă ..j<=n..}..... Se foloseşte an tablou unidimensional. cout<<"m="......... cout<<"n='".. . ... cin>>m...... cin>>el[i]>>e2[i].. u[i].ui reprezintă arcul i...y]=1.....i<=m. k=0.......... int n..... int y...... i++) for (j=1.......are m componente.x][u[i].j++) if (a[i][j] ==1) { k=k+1.. ......

U) un graf orientat. .. Se numeşte componentă tare conexă.... ObservaŃie. dacă pentru oricare dou ă vârfuri x şi y există un drum în G de la x la y şi un drum de la y la x. U) un graf orientat..x=i. nu este depistată nici o componentă tare conexă ( nc=0).graf tare conex .. u[k].y =j.if (a[i][j]==1) { k=k+1. Componente tare conexe În această secŃiune. Graful G se numeşte tare conex. . • Exemplu. oricare ar fi vârfurile x şi y.se parcurg nodurile grafului.este tare conex.subgraful generat de nodurile 1. u[k]. . 5. 3. vor fi prezentate noŃiunile: . Fie graful orientat prezentat în figura de mai jos: 1 3 Acest graf are două componente tare conexe: . există un drum in G de la x la y şi un drum de la y la x. .subgraful generat de nodurile 4. 8... U) un graf orientat: Graful G este tare conex. . deoarece. un graf orientat G1 =(V1.este subgraf al grafului G . dacă admite o singură componentă tare conexă. cu i. 19 . Componentă tare conexă DefiniŃie. U1) care verifică următoarele condiŃii: . subgraful lui G generat de V1U{x} nu mai este tare conex .dacă i nu a fost introdus în nici o componentă tare conexă..la început.oricare are fi x ∈ V-V1. 1 Graful este tare conex... nici un nod nu face parte din vreo componentă tare conexă (luate=[ ])...deci. 6.. ..algoritmul de descompunere a unui graf în componente tare conexe Graf tare conex DefiniŃie.. Algoritmul de descompunere a unui graf în componente tare conexe Algoritmul procedează astfel: .componentă tare conexă . Fie G=(V. 2. Fie G=(V. • Exemplu de graf tare conex. Graf tare conex. Fie G=(V..} m=k.

se construieşte noua componentă tare conexă. s-au folosit: FuncŃiile: Succesori(i. S):care pune în şirul S toate nodurile j.i<=ns.h> typedef int mat[20][20]. ns. P.. sir comp[50]. cu proprietatea că există drum între ele şi i. şi se reunesc cu {i}.se intersectează predecesorii lui i cu succesorii săi. în limbajul C++. i.} } void intersectie(sir S. j. Vectorul: Comp :ale cărui componente. for (j=1.j++) if (S[i]==P[j]) ok=1. din graf. #include <iostream.h> #include <stdio. void succesori(int i. np=0.se măreşte numărul componentelor tare conexe cu 1. int& np) { int j. mat d. Variabilele: d : matricea drumurilor. cu proprietatea că există drum între i şi ele. la final. sir S. sir P. x[nx]=S[i]. j.h> #include <conio.i++ ) {ok=0. typedef int sir[20]. for (i=1. din graf . sir P. nc. for (j=1.j<=np. if (ok==1) {nx++. int i. cu ajutorul programului prezentat mai jos. componentele tare conexe. S[ns]=j. ncomp.} } 20 . ns=0. int& ns) {int j.j<=n. for (j=1.j<=n. astfel: . P[np]=j. P):care pune în şirul P toate nodurile j. int ok. int np. np. În program. Predecesori(i. sir S. nc : reprezintă numărul componentelor tare conexe depistate. n. vor reŃine. Pentru implementarea acestui algoritm. care sunt şiruri de elemente. luate : un şir care reŃine toate nodurile care fac deja parte dintr-o componentă tare conexă. . int ns. int& nx) {int ok.j++) if (d[i][j]==1) {ns=ns+1.} } void predecesori(int i. luate. au mai fost folosite şi alte variabile dar deoarece rolul lor reiese foarte uşor din urmărirea programului nu-l mai comentăm.nl. nx=0. sir x. m.j++) if (d[j][i]==1) {np=np+1.

fiind dat graful G=(V.j<=ncomp[nc]. for (j=1.S. cu matricea costurilor asociată C ∈ Mn (R). for (i=1. Fiind dat graful G=(V. nl=0.i<=n. dintr-un graf.U).ns). luate[nl]=comp[nc] [j]. } 9.i++) {cout<<"component tare conexa cu numarul "<<i<<endl.j++) cout<<comp[i][j]<<" ". dintr-un graf.j++) {cout<<"d["<<i<<". cu matricea costurilor asociată C ∈ Mn(R). for (j=1."<<j<<"]". predecesori(i. unde: 21 . să se determine drumurile de lungime minimă (maximă) între vârfurile i şi j.i++) {ok=0. intersectie(S. if(ok==0) {nc++. cin>>d[i][j].j++) {nl++.np. Fiind dat graful G=(V. aşa cum sugerează şi titlul. definită astfel: C ∈ Mn (R).} nc=0. cout<<endl. cout<<"n=". succesori(i. cu matricea costurilor asociată C ∈ Mn (R).} } } for (i=1. . modurile de tratare a problemelor care fac parte din următoarele două mari clase de probleme: .i<=nc.comp[nc].j<=n. Problemele de minim (maxim) se pot enunŃa astfel: 1.ncomp[nc]). să se determine drumurile de lungime minimă (maximă) între vârful i şi toate celelalte vârfuri.np). Drumuri minime şi maxime NoŃiuni generale În această secŃiune vor fi prezentate.probleme în care se cere determinarea drumurilor minime.i<=n.} getch().U).ns.j<=ncomp[i].U). 3.i++) for (j=1.} void main() {clrscr().j++) if (luate[j]==i) ok=1. for (i=1. 2.P. U) i se asociază matricea costurilor. Fiind dat graful G=(V. În cazul problemelor de minim. cin>>n. for (j=1.probleme în care se cere determinarea drumurilor maxime.P. să se determine drumurile de lungime minimă (maximă) între oricare dou ă vârfuri.j<=nl. forma 1 .

.j. într-un şir de n transformări aplicate matricei costurilor C. n for i=1 . daca i ≠ j si (i. B∈ Mn (R).e10.. daca i = j ∞. ca de exemplu. care are matricea costurilor C. j ) ∉ U   • Exemplu: Fiind dat graful din figura de mai jos (costul fiecărui arc fiind scris pe ea) 1 13 3 matricea costurilor se scrie in felul următor: Forma 1:  c11 c12 c13 c14   0 11 ∞ 13       c21 c22 c23 c24   ∞ 0 15 12  C = = c31 c32 c33 c34   ∞ ∞ 0 ∞      c     41 c42 c43 c44   ∞ ∞ 14 0  Forma 2: 11 − ∞ 13   c11 c12 c13 c14   0     15 12   c21 c22 c23 c24   − ∞ 0 C = = c31 c32 c33 c34   − ∞ − ∞ 0 − ∞      c c42 c43 c44   − ∞ − ∞ 14 0   41    ObservaŃii.n}care se poate implementa astfel: for k=1 ..j). şi anume. 22 . Matricea costurilor forma 1 diferă de matricea costurilor forma 2 prin faptul că în loc de ∞ apare -∞. Algoritmul are la bază următoarea idee: "Dacă drumul minim de la nodul i la nodul j trece prin nodul k.j].j=minim(ci. 2: În program nu se poate scrie ∞ sau -∞. Algoritmul Roy-Floyd Acest algoritm se aplică în cazul problemelor în care se d ă un graf G=(V.e10. j ) ∉ U   În cazul problemelor de maxim. pentru ∞ : const p infinit = 1. j = 0. unde: cos t . fiind dat graful G=(V. şi se cere să se determine lungimea drumurilor minime. definită astfel: C ∈ Mn (R). n if (c[i.. daca i ≠ j si (i. daca int re i si j exista un arc cu cos tul cos t   ci . U) i se asociază matricea costurilor. între oricare două noduri ale grafului. precum şi de la nodul k la nodul j. atunci şi drumul de nodul i la nodul k.ci. j = 0. de aceea recomandăm ca atunci când trebuie folosite să se definească două constante foarte mari. daca int re i si j exista un arc cu cos tul cos t   ci . n for j=l . forma 2..k+ck.k]+c[k. 1.cos t . astfel: Tk(C)=B ..k]+c[k. daca i = j − ∞.j ∈ {1.i. vor fi prezentaŃi:algoritmul Roy-Floyd şi algoritmul lui Dijkstra. U). şi în unele cazuri şi nodurile care constituie drumurile respective..j]=c[i...j]<c[i. În continuare. de fapt. bi. pentru -∞ : const m infinit=-1. este minim" şi constă. vor fi prezentaŃi doi algoritmi care permit rezolvarea unor probleme de minim (maxim). ObservaŃie.j]) c[i.

} {while(f>>i>>j>>c) a[i][j]=c. typedef sir matmul[20][20]. "<<y. else a[i][j]=p_inf.} void drum(int i.j ∈ { 1.j++) transformare().int j) { int k. a[i][j]=a[i][k]+a[k][j]. atunci costul drumului iniŃial de la i la j se va înlocui cu costul drumului i-k-j.h> {drum(i. k. for(j=1.t.. 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 {for(k=1. costurilor cout<<"y=".n.val. gasitk. gasit=1. else cout<<"nu exista drum".} void main() void transformare() //se transforma matricea {cout<<"x=".i++) {cout<<"drumul minim de la nodul "<<x<<" la nodul for(j=1.k<=n&&!gasit. se execută: dacă costul drumului între nodurile i şi j este mai mic decât suma costurilor drumurilor între nodurile i şi k şi între nodurile k şi j.. unde i.. ObservaŃie.int y)//afiseaza costului de drum void init() //se initializeaza matr costurilor minim si nodurile care formeaza drumul {f>>n.. int i. matmul d.} getch(). #include<fstream. ld.in").} ifstream f("rf. void citire()//se actualizeaza matr costurilor cu cout<<x<<" ".h> #include <conio. acest lucru făcându-se prin modificarea matricei costurilor. if(!gasit) cout<<j<<" ". {if(a[x][y]<p_inf) for(i=1.m. j.h> const p_inf=10000. evident. mat c.Descrierea detaliată a algoritmului prezentat mai sus: Pentru fiecare pereche de noduri (i. Dacă se doreşte şi afişarea nodurilor care compun efectiv aceste drumuri.c.j<=n. nd. se procedează astfel: se parcurg cu k toate nodurile grafului.j. diferite de i şi j.i++) citire().i<=n.y).} f.j).j++)if(i==j) a[i][j]=0.i<=n. {for(k=1. for(i=1.n}. în C++.} int const p_inf=10000. int j) //se det nodurile drumului minim În continuare.k<=n. permite decât calcularea lungimii drumurilor minime între oricare dou ă noduri ale grafului. sir dr.h> #include <stdio. care implementează algoritmul comentat anterior #include <iostream.i.x.} cout<<" are costul "<<a[x][y]<<endl.y).k++) #include<iostream. datele din fisier drum(x. pentru fiecare nod k.k. if(a[i][k]+a[k][j]<a[i][j]) afisare(x.j<=n. void drum_de_la(int i.y.gasit=0. typedef int sir[20].k). se prezintă programul. cin>>y.j).x.k++) init().y. int a[50][50]. typedef int mat[20][20]. cin>>x.h> if((i!=k&&j!=k)&&a[i][j]==a[i][k]+a[k][j]) #include<conio.h> drum(k. n. Algoritmul prezentat în forma de mai sus. if (i!= j){ 23 . void afisare(int x.close().

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

şi se cere să se determine lungimea drumurilor minime de la un nod dat x până la fiecare nod din graf se selectează nodurile grafului unul câte unul în ordinea crescătoare a costului drumului de la nodul pl la ele. care are matricea costurilor C. Pentru calcularea drumurilor de lungime minimă se întreŃine o mulŃime D în care se memorează costul drumurilor de la nodul x la nodurile neselectate.nd[k][j]. else if (c[i][j]>c[i][k]+c[k][j]) { c[i][j]=c[i][k]+c[k][j].nd[i][j].} Algoritmul lui Dijkstra Acest algoritm se aplică în cazul problemelor în care se d ă un graf G=(V. U).î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ă. costuri care se recalculează la fiecare extragere de nod. cin>>x>>y>>val. Cât timp coada de priorităŃi Q nu este vidă execută: Pas 4. în mulŃimea s.i<=n.d[i][j]. se citeşte nodul iniŃial x şi se atribuie mulŃimii S Pas 2.i<=m.j<=n. getche(). for (k=1.j++) if ((i!=j) && (c[i][j]<p_inf)) { nd[i][j]=1.nd[k][j].d[i][j].j++) if (c[i][j]==c[i][k]+c[k][j]) reuneste(d[i][j].nd[i][j]). cout<<endl.} for (i=1.i<=n.nd[i][j]). Se iniŃiază mulŃimea D cu costurile drumurilor de la nodul x la toate celelalte noduri ale grafului Pas 3.i++) {for (j=1. care are matricea costurilor C. Se folosesc 3 vectori: . atunci el va fi noul cost. Dacă acest cost este mai mic decât cel din mulŃimea D. Se iniŃializează mulŃimea S cu mulŃimea vidă. face_sirul(d[k][j]. se adaugă nodul y la mulŃimea S (se extrage din coada de priorităŃi Q şi se declară ca nod selectat) Pas 6.j++) cout<<c[i][j]<<" ".j<=n.k++) for (i=1. Pas 1. .for (i=1. c[x][y]=val.} for (i=1. care iniŃial conŃine doar nodul pl.i++) {cout<<"x y val " . U).. Se recalculează costul drumului de la nodul x la acest nod folosind ca nod intermediar nodul extras Pas 8. Pentru fiecare nod neselectat execută: Pas 7. 25 .k<=n.un nod y este selectat atunci când s-a determinat costul final al drumului cu costul minim de la nodul sursa x la el.Vectorul d conŃine costul drumurilor .j<=n.} afis().i++) for (j=1.i<=n.i++) for (j=1.d[k][j]. se caută printre nodurile selectate nodul y cu cel mai mic cost al drumului Pas 5. d[i][j][1]=i.} else nd[i][j]=0. şi se cere să se determine lungimea drumurilor minime de la un nod dat x până la fiecare nod din graf Algortimul reŃine în mulŃimea S nodurile care au fost deja selectate şi într-o coadă de priorităŃi Q nodurile care nu au fost deja selectate adică Q=V-S.Vectorul t memorează drumurile găsite î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.Vectorul s pentru mulŃimea nodurilor selectate . astfel: .

. p entru fiecare vârf al grafului. iar valoarea vârfulu i selectat p(j) ←poz (d rumul trece p rin acest vârf) Pas 3.se co mp letează co mponentele vecto rulu i d astfel d [i]=c[pl.i]. reŃine suma d(j) ←d(poz) +a(poz.i] ≠∞. dacă i≠p l şi c[p l.. pro ced ând astfel: -se compară costu l existent în vecto ru l d.. . u tilizând ca nod intermed iar no du l selectat. d(j). 1 0 2 ∞ 3 2 4 ∞ 5 ∞ 6 2 26 d . În cazul în care suma este mai mică.d[i]=c[pl.. se trasează dru mul de la pl la el.. p[i]= p1. şi distanŃa de la nodul selectat. 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 stabileşte nodul de plecare: p1=1 Se completează vectorii d şi p.. la nodul pentru care se face actu alizarea distanŃei. poz. c: reprezintă matricea costurilor asociată grafului.j) şi elemetul din p corespunzător acelu aşi vârf. Fie p oz acest vârf . d .i] ≠∞. adăugând u-l mu lŃimii s. j. p t j.se co mp letează co mponentele vecto rulu i p astfel: p entru i=1 .n.se citeşte no du l de p lecare pl. cu su ma dintre co stul existent în d p entru nodul selectat. pentru i=1. astfel: . cu excepŃia lui p l.Algoritmul folo seşte urmă toa rele varia bile: n: reprezintă numărul de noduri ale grafului.indică mulŃimea nodurilor selectate( 0 dacă i nu este selectat.i].vect costului drumurilor p-indică drumurile găsite între nodul pl şi celelalte noduri din graf (pt nodul i se reŃine nodul precedent pe unde trece drumul de la pl la i. poz. p[i]=0.pentru nodurile neselectate.::n. pentru i=1. d [pl]=0 . j. 1 dacă i este selectat) şi procedează a stfel: Pas1 . po z. p[i]=0. elementu l d in d corespunzăto r nodu lu i pentru care se face actu alizarea.n. se actualizează în d co stul dru mu rilo r de la p l la ele.j) .se execută de n-1 o ri u rmăto arele: . (în componentele vectorului d se trec elementele de pe prima linie din C) .printre no du rile neselectate se cau tă cel aflat la distanŃa minimă faŃă de pl şi se selectează. altfel. p as2.pentru i=1.n şi i≠p l.. pt pl se reŃine 0) s. p[i]=p1. altfel. j: d (po z)←a(poz. . dacă i≠pl şi c[pl.

2} d p 1 0 0 2 3 2 1 4 5 6 Se completează componentele vectorilor d şi p.5}. d4.2)=min(∞. ∞. d3+C3. d3+C3.5.2)=min(∞. pentru că d ă min{∞. nealese={2. 5} 1 2 3 4 5 6 2 4 2 d 0 1 6 1 p 0 Se completează componentele vectorilor d şi p.4+3)=7 (d2 =7 şi p 2 =4) 5 : min(d5.4. se alege nodul j pentru care dj=min{d2. astfel: 2 : min(d2. pentru nodurile nealese. d 5}.2+2)=2 (d 5 şi p 5 rămân nemodificate) 1 0 0 2 ∞ 0 3 2 1 4 ∞ 0 5 ∞ 0 6 2 1 d p Pasul 3 Dintre nodurile nealese încă. se alege j=3. 5}.4. se alege nodul j pentru care dj=min{d2. d6}.5)=min(∞. pentru nodurile nealese.4.2+3)=5 (d5=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ă.5)=min(5. nealese={2. pentru nodurile nealese.4)=min(∞. d5. se alege j=5. d3. se alege j=4.2+ ∞)= ∞ (d 2 şi p 2 rămân nemodificate) 4 : min(d4. deci. se alege j=6.5)=min(∞. d6+C6. ∞. d4+C4. pentru că d6 =min{∞. d 5. astfel: 2 : min(d2. se alege nodul j pentru care dj=min{d 2.2+2)=4 (d4=4 şi p4=6) 5 : min(d5.4) =min(∞. ∞. d3+C3.6}. d6}.3.6}. deci. nealese={2. 2. d6+C6. d3+C3.2)=min(∞. d6+C6.2+ ∞)= ∞ (d 2 şi p 2 rămân nemodificate) 4 : min(d4. pentru ca d3 =min{∞.5}. d 4. se alege nodul j pentru care dj=min{d 2. deci. nealese={2.5. d5}. 2} d p 1 0 0 2 3 2 1 4 5 6 2 1 Se completează componentele vectorilor d şi p.6)=min(2.2+ ∞)=∞ (d 5 şi p 5 rămân nemodificate) 6 : min(d6. astfel: 2 : min(d2. ∞.p 0 0 1 0 0 1 Pasul 2 Dintre nodurile nealese încă. d4. 27 . d4+C4. 4. pentru ca d5 =min{∞.4+∞)=5 (d5 şi p5 rămân nemodificate) 1 0 0 2 7 4 3 2 1 4 4 6 5 5 6 6 2 1 d p Pasul 5 Dintre nodurile nealese încă.2+ ∞)=∞ (d 4 şi p 4 rămân nemodificate) 5 : min(d5. deci.

for(j=1.} for(i=1.h> ifstream f("d. 3 4: p4 =6.j<=n. poz=j. deci. de la 1 la 2 avem : 1.1 p6 =1. for(j=1.j<=n.j<=n.j++) if(s[j]==0 && d[j]>d[poz]+a[poz][j]) 28 . 5 6.S+ ∞)=7 (d2 şi p2 rămân nemodificate) 1 0 0 2 7 4 3 2 1 4 4 6 5 5 6 6 2 1 d p Concluzii: Drumurile minime de la nodul 1 la celelalte noduri sunt: 2: p2=4. } void main() {f>>n. d5+C5. deci. float a[50][50]. p6=1. de la 1 la 5 avem : 1. deci. for(i=1.i++) {d[i]=a[pl][i]. pentru nodurile nealese. 6.i++) for(j=1. de la 1 la 3 avem : 1. 6.2)=min(7.i. astfel: 2 : min(d2.p[50]. const p_inf=10000. 6.} s[poz]=1. 6 #include<iostream. deci.c.min.i<=n. if(i!=pl&&d[i]<p_inf) p[i]=pl.poz.s[50]. p 6=1. deci.d p 1 0 0 2 3 2 1 4 4 6 5 5 6 6 2 1 Se completează componentele vectorilor d şi p. else a[i][j]=p_inf. cout<<i<<" ".4 5: p5=6.d[50].i<=n-1. p 4=6.in"). de la 1 la 4 avem : 1.close().h> #include<conio. void drum (int i) {if(p[i]!=0) drum(p[i]). cin>>pl. f. 4.pl.h> #include<fstream. while(f>>i>>j>>c) a[i][j]=c.i<=n.j++) if(s[j]==0) if(d[j]<min) {min=d[j]. de la 1 la 6 avem : 1. for(i=1. 2 3: p3=1.i++) {min=p_inf. p6 =1.j.j++) if(i==j) a[i][j]=0. int n. cout<<"pl=".

ifstream f("rf. if(i!=x &&d[i]<p_inf) p[i]=x. cout<<i<<" ".} void generare_drum(int x) //se genereaza drumurile { s[x]=1.i++) for(j=1.i++) cout<<d[i]<<" ".} else cout<<"Nu exista drum de la "<<pl<<" la "<<i<<endl.j<=n. for(i=1.min.j<=n.y.i++) {for(j=1.j++) if(s[i]==0&&d[j]>d[y]+a[y][j]) {d[j]=d[y]+a[y][j].j<=n.} s[y]=1.i<=n. else a[i][j]=p_inf.n. y=j.x.in").d[100].i<=n. p[j]=poz.c. getch().} void afisare(int x) {for(i=1.{d[j]=d[poz]+a[poz][j]. cout<<endl.} void citire()//se actualizeaza matr costurilor cu datele din fisier {while(f>>i>>j>>c) a[i][j]=c.h> int a[50][50].i.i<=n.h> #include<fstream.j.i<=n.j++) if(s[j]==0&&d[j]<min) {min=d[j]. for(i=1.} } for(i=1. for(i=1.p[100].i<=n.s[100].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.} }} void drum(int i) {if (p[i]!=0) drum (p[i]). for(i=1.close().i<=n. f.i++) if(i!=x) 29 .} min=p_inf. int const p_inf=10000. p[j]=y. for(j=1. void init()//se initiealizeaza matr costurilor {f>>n.} //algoritmul dijkstra #include<iostream.i++) {d[i]=a[x][i].h> #include<conio. cout<<endl.j++)if(i==j) a[i][j]=0.

drum(i). init().} void main() {cout<<"x=".if(p[i]!=0) {cout<<"drumul cu costul minim de la nodul "<<x. citire(). cout<<endl. generare_drum(x).} else cout<<" nu exista drum de la "<<x<<" la "<<i<<endl. afisare(x). cout<<" la nodul "<<i<<" are costul "<<d[i]<<endl. getch().} 30 . cin>>x.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->