Sunteți pe pagina 1din 21

Grafurile

Sandor Sergiu, cls a X-a A.

Graf orientat
Un graf orientat reprezinta o pereche ordonata de multimi G=(X,U), unde X este o multime finita si nevida, numita multimea nodurilor, si U este o multime formata din perechi ordonate de elemente ale lui X, numita multimea arcelor. Exemplu

In graful din fig. 1 multimea nodurilor este X={1, 2, 3, 4, 5, 6, 7} si multimea arcelor este U={u1, u2, u3, u4, u5, u6, u7, u8, u9, u10}={(1,2), (2,3), (3,4), (4,1), (3,5), (5,3), (5,6), (6,7), (7,6), (7,5)}.

Conexitate in grafuri orientate


Un graf G este conex, daca oricare ar fi doua varfuri ale sale, exista un lant care le leaga. Un lant intr-un graf orientat este un sir de arce {u 1, u 2, u3 , , un} cu proprietatea ca oricare doua arce consecutive au o extremitate comuna. Altfel spus, un lant este un traseu care uneste prin arce doua noduri numite extremitatile lantului, fara a tine cont de orientarea arcelor componente. Exemplu

Graful este conex pentru ca oricum am lua doua noduri putem ajunge de la unul la celalalt pe un traseu de tip lant. De exemplu, de la nodul 4 la nodul 2 putem ajunge pe traseul de noduri (4,3,2) stabilind astfel lantul {u5, u3}, dar si pe traseul de noduri (4,1,2) stabilind lantul {u 6, u2}

Acest graf nu este conex. Luand submultimea de noduri {1,2,3}, putem spune ca intre oricare doua noduri din aceasta submultime exista cel putin un lant., de exemplu lantul {u1, u2} sau {u3, u1}. La fel stau lucrurile cu submultimea de noduri {4,5,6}. Dar nu ptuem gasi un lant intre un nod din prima submultime si un nod din a doua submultime. Plecand dintr-un nod al primei submultimi si deplasandu-ne pe arce, nu avem cum sa trecem in a doua submultime pentru ca nu exista nici un arc direct care sa lege cele doua submultimi. De exemplu plecand din nodul 1 putem ajunge in nodul 2 pe traseul {u 3, u2}, dar

de aici nu putem ajunge mai departe in nodul 4, deci nu exista lant de la 2 la 4.

Componenta conexa
Componenta conexa a unui graf G=(X, U), reprezinta un subgraf G1=(X1, U1) conex, a lui G, cu proprietatea ca nu exista nici un lant care sa lege un nod din X 1 cu un nod din X-X 1 (pentru orice nod, nu exista un lant intre acel nod si nodurile care nu fac parte din subgraf). De exemplu graful din fig. 3 nu este conex , insa in el distingem doua componente conexe: G1 =(X1, U1), unde X1={1,2,3} si U1={u1, u2, u3}; si G2=(X2, U2), unde X2={4,5,6} si U2={u4, u5}. Graf tare conex Graful tare conex este un graf orientat G=(X, U), daca pentru oricare doua noduri x si y apartin lui X, exista un drum de la x la y precum si un drum de la y la x. Exemplu

Graful cu n=3 din fig. 4 este tare conex. Pentru a demonstra acest lucru, formam toate perechile posibile de noduri distincte (x, y) cu x, y apartin multimii {1,2,3}, si pentru fiecare astfel de pereche cautam un drum de la x la y si un drum de la y la x. x=1, y=2 De la 1 la 2 drumul [1,3,2], pe arcele (1,3) si (3,2); De la 2 la 1 drumul [2,3,1], pe arcele (2,3) si (3,1). x=1, y=3 De la 1 la 3 drumul [1,2,3], pe arcele (1,2) si (2,3); De la 3 la 1 drumul [3,2,1], pe arcele (3,2) si (2,1). x=2, y=3 De la 2 la 3 drumul [2,1,3], pe arcele (2,1) si (1,3); De la 3 la 2 drumul [3,1,2], pe arcele (3,1) si (1,2).

Componenta tare conexa

Un subgraf se obtine dintr-un graf G= (X, U) eliminand niste varfuri si pastrand doar acele muchii care au ambele extremitati in multimea varfurilor ramase. Fie un subgraf tare conex G1=(X1, U1) al grafului G=(X, U). Adaugam la subgraf un nod x care nu face parte din multimea nodurilor sale (x apartine X-X1). Obtinem astfel multimea de varfuri X1 reunit cu {x}. Subgraful indus pe multimea X1 reunit cu {x} se obtine luand si arcele care trec prin nodul x. Daca acest subgrafnu mai este tare conex, atunci el se numeste componenta tare conexa. Exemplu

Acesta este graful G=(X,U) tare conex. Din el eliminam nodul 4.

Am obtinut astfel subgraful tare conex G1=(X1, U1). Acestui graf ii adaugam un nod x care nu face parte din multimea nodurilor subgrafului G1. Graful obtinut este componenta tare conexa.

Problema
Stabiliti daca graful de mai jos este sau nu conex.

X= {1, 2, 3, 4, 5};

U= {u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15, u16}={(1,2), (2,1), (3,2), (2,3), (4,3), (3,4), (1,4), (4,1), (2,5), (5,2), (3,5), (5,3), (4,5), (5,4), (1,5), (5,1)}. De la 1 la 2 pe drumul [1,5,2] sau [1,5,4,3,2], etc. De la 1 la 3 pe drumul [1,5,3] sau [1,5,2,3], etc. De la 1 la 4 pe drumul [1,5,4] sau [1,5,2,3,4], etc. De la 1 la 5 pe drumul [1,2,5] sau [1,4,5], etc. De la 2 la 3 pe drumul [2,5,3] sau [2,1,5,3],etc. De la 2 la 4 pe drumul [2,5,4] sau [2,3,5,4], etc. De la 2 la 5 pe drumul [2,1,5] sau [2,3,5], etc. De la 3 la 4 pe drumul [ 3,5,4] sau [3,2,5,4], etc. De la 3 la 5 pe drumul [3,2,5] sau [3,4,5], etc. De la 4 la 5 pe drumul [4,1,5] sau [4,3,5], etc.

Grafuri neorientate
Graf = orice mulime finit V prevzut cu o relaie binar intern E. Notm graful cu G=(V, E). Graf neorientat = un graf G=(V, E) n care relaia binar este simetric: (v,w) E atunci (w,v) E. Nod = element al mulimii V, unde G=(V, E) este un graf neorientat. Muchie = element al mulimii E ce descrie o relaie existent ntre dou vrfuri din V, unde G=(V, E) este un graf neorientat;
1 6 5 3 4

In figura alaturata: V={1,2,3,4,5,6} sunt noduri E={[1,2], [1,4], [2,3],[3,4],[3,5]} sunt muchii

G=(V, E)=({1,2,3,4,5,6}, {[1,2], [1,4], [2,3],[3,4],[3,5]})

Adiacenta: ntr-un graf neorientat existena muchiei (v,w) presupune c w este adiacent cu v i v adiacent cu w. n exemplul din figura de mai sus vrful 1 este adiacent cu 4 dar 1 i 3 nu reprezint o pereche de vrfuri adiacente. Inciden = o muchie este incident cu un nod dac l are pe acesta ca extremitate. Muchia (v,w) este incident n nodul v respectiv w. Grad = Gradul unui nod v, dintr-un graf neorientat, este un numr natural ce reprezint numrul de noduri adiacente cu acesta (sau numarul de muchii incidente cu nodul respectiv) Nod izolat = Un nod cu gradul 0. Nod terminal= un nod cu gradul 1
1 6 5

Nodul 5 este terminal (gradul 1). Nodul 6 este izolat (gradul 0)

2 3 4

Nodurile 1, 2, 4 au gradele egale cu 2.

Lan = este o secven de noduri ale unui graf neorientat G=(V,E), cu proprietatea c oricare dou noduri consecutive din lant sunt adiacente: L=[w1, w2, w3,. . ,wn] cu proprietatea c (wi, wi+1) E pentru 1 i<n. Lungimea unui lan = numrul de muchii din care este format. Lan simplu = lanul care conine numai muchii distincte

Lan compus= lanul care nu este format numai din muchii distincte Lan elementar = lanul care conine numai noduri distincte Ciclu = Un lan n care primul nod coincide cu ultimul. Ciclul este elementar dac este format doar din noduri distincte, excepie fcnd primul i ultimul. Lungimea unui ciclu nu poate fi 2. Succesiunea de vrfuri 2, 3, 1 6 5, 6 reprezint un lan simplu i elementar de lungime 3. 5 Lanul 5 3 4 5 6 este simplu 2 dar nu este elementar. 3 4 Lanul 5 3 4 5 3 2 este compus i nu este elementar. Lanul 3 4 5 3 reprezint un ciclu elementar Graf partial = Dac dintr-un graf G=(V,E) se suprim cel puin o muchie atunci noul graf G=(V,E), E E se numete graf parial al lui G.
1 6 5 3 4 1 6 5 3 4

G partial al lui G

G1 este graf

Subgraf = Dac dintr-un graf G=(V,E) se suprim cel puin un nod mpreun cu muchiile incidente lui, atunci noul graf G=(V,E), E E si V V se numete subgraf al lui G.
1 6 5 3 4 6 5 3

G este graf partial al lui G Graf regulat = graf neorientat n care toate nodurile au acelai grad;

G1

6 5 3 4

Graf complet = graf neorientat G=(V,E) n care exist muchie ntre oricare dou noduri. Numrul de muchii ale unui graf complet este: nr*(nr1)/2.Unde nr este numarul de noduri
1

graf complet. Nr de noduri: 4x(4-1)/2 = 6 Graf conex = graf neorientat G=(V,E) n care pentru orice pereche de noduri (v,w) exist un lan care le unete.
1 6 5 3 4
1 6 5 3 4

graf conex

nu este graf

conex Component conex = subgraf al grafului de referin, maximal n raport cu proprietatea de conexitate (ntre oricare dou vrfuri exist lan);

6 5 3 4

graful nu este conex. Are 2 componente

conexe: 1, 2 si 3, 4, 5, 6 Lan hamiltonian = un lan elementar care conine toate nodurile unui graf
1 6 5 3 4

L=[2

,1,

6,

5,

4,

3]

este

lant

hamiltonian Ciclu hamiltonian = un ciclu elementar care conine toate nodurile grafului

6 5 3 4

C=[1,2,3,4,5,6,1] este ciclu hamiltonian

Graf hamiltonian = un graf G care conine un ciclu hamiltonian Graful anterior este graf Hamiltonian. Lan eulerian = un lan simplu care conine toate muchiile unui graf

6 5 3 4

Lantul: L=[1.2.3.4.5.3.6.2.5.6] este lant eulerian Ciclu eulerian = un ciclu simplu care conine toate muchiile grafului Ciclul: C=[1.2.3.4.5.3.6.2.5.6.1] este ciclu eulerian Graf eulerian = un graf care conine un ciclu eulerian. Condiie necesar i suficient : Un graf este eulerian dac i numai dac oricare vrf al su are gradul par.

Reprezentarea grafurilor neorientate


Fie G=(V, E) un graf neorientat. Exista mai multe modalitati de reprezentare pentru un graf neorientat, folosind diverse tipuri de structuri de date. Reprezentarile vor fi utilizate in diversi algoritmi si in programele care implementeaza pe calculator acesti algoritmi. Matricea de adiacent matricea boolean Matricea de adiacent asociat unui graf neorientat cu n noduri se defineste astfel: A = (ai j) n x n cu 1, daca [i,j]E a[i,j]= 0, altfel

Observatii: - Matricea de adiacenta asociat unui graf neorientat este o matrice simetric - Suma elementelor de pe linia k reprezint gradul nodului k - Suma elementelor de pe coloana k reprezint gradul nodului k Fie graful din figura urmatoare:

6 5 3 4

A=

0 1 0 1 0 0 nodul 1 are gradul 2 1 0 1 0 0 0 nodul 2 are gradul 2 0 1 0 1 1 0 nodul 3 are gradul 3 1 0 1 0 0 0 nodul 4 are gradul 2 0 0 1 0 0 0 nodul 5 are gradul 1 0 0 0 0 0 0 nodul

6 are gradul 0 Numarul de noduri este 6 si numarul de muchii este 4 Matricea este simetrica si patratica avand 6 linii si 6 coloane Diagonala principala contine numai valori nule Pentru a prelucra graful se citesc: 6- reprezentand n, numarul de noduri 4- reprezentand m, numarul de muchii 4 perechi x-y reprezentand extremitatile celor 4 muchii: 1-2 => a[1,2]=a[2,1]=1 1-4 => a[1,4]=a[4,1]=1 2-3 => a[2,3]=a[3,2]=1 3-4=> a[3,4]=a[4,3]=1 3-5 => a[3,5]=a[5,3]=1 Probleme propuse:

Problema 1 Se citeste un graf din fisierul graf.txt: numarul de noduri, numarul de muchii si muchiile. a) sa se afiseze matricea de adiacente b) Sa se determine gradul unui nod citit c) Sa se afiseze pentru un nod citit nodurile adiacente d) sa se afiseze nodurile incidente cu cea de a x muchie din matrice e) sa se afiseze pentru fiecare nod gradul f) sa se afiseze nodul (nodurile) avand cei mai multi vecini g) sa se afiseze nodurile izolate Problema 2 Sa se det daca o matrice citita dintr-un fisier poate fi matricea unui graf neorientat. In caz afirmativ se va determina cate muchii are graful Problema 3 Sa se genereze un graf avand maxim n noduri si maxim m muchii. Sa se afiseze matricea atasata Observatie: graful nu poate fi decat cel mult complet

Listele de adiacenta a nodurilor


Reprezentarea in calculator a unui graf se poate face utilizand listele de adiacenta a varfurilor, adica pentru fiecare varf se alcatuieste lista varfurilor adiacente cu el. Fie graful din figura urmatoare:
1 6 5 3 4

Lista vecinilor nodului 3: 2, 4, 5 (noduri adiacente)

6 5 3 4

Nodul 6 nu are vecini (este izolat) Pentru intreg graful vom avea mai multe liste : Nodul 1 : 2 4 Nodul 2 : 1 Nodul 3 : 2 Nodul 4 : Nodul 5 : Ordinea nodurilor in cadrul unei liste nu este importanta Pentru a genera o astfel de lista vom defini tipul nod : struct nod {int nd; nod *next;}; Toate listele se vor memora utilizand un vector de liste : nod *L[20]; Datele de intrare : numarul de noduri si muchiile se vor citi din fisier : O solutie de implementare este urmatoarea : #include<conio.h> #include<fstream.h> struct nod {int nd; nod *next;}; nod *L[20]; void afisare(int nr_nod) //afiseaza lista vecinilor nodului nr_nod
1 3 3 4 3 5

{nod *p=L[nr_nod]; if(p==0) cout<<nr_nod<<" este izolat "<<endl; else {cout<<"lista vecinilor lui "<<nr_nod<<endl; nod *c=p; while(c) {cout<<c->nd<<" "; c=c->next;} cout<<endl;} } void main() {fstream f;int i,j,n; nod *p,*q; f.open("graf.txt",ios::in); //citirea datelor din fisier clrscr(); f>>n; while(f>>i>>j) {p=new nod; //se adauga j in lista vecinilor lui i p->nd=j; p->next=L[i]; L[i]=p; q=new nod; //se adauga i in lista vecinilor lui j q->nd=i; q->next=L[j]; L[j]=q; } f.close(); cout<<endl<<"listele de adiacente "; for(i=1;i<=n;i++) afisare(i); getch(); } Observatie : In exemplul anterior adaugarea unui nou element in lista se face inainte celorlalte din lista corespunzatoare.

Aceste doua moduri de reprezentare (prin matrice de adiacenta si prin liste de vecini) se folosesc dupa natura problemei. Adica, daca in problema se doreste un acces frecvent la muchii, atunci se va folosi matricea de adiacenta; daca numarul de muchii care se reprezinta este mult mai mic dect nxn, este de preferat sa se folosesca listele de adiacenta, pentru a se face economie de memorie. Probleme propuse : 1. 1. Sa se memoreze un graf neorientat utilizand liste de adiacente. Parcurgand listele de adiacenta rezolvati urmatoarele cerinte : a. b. c. d. e. f. a. b. c. d. e. f. Sa se determine daca graful contine noduri izolate Sa se determine fradul unui nod citit de la tastatura Sa se determine nodul cu cel mai mare grad Sa se determine daca nodurile x si y sunt adiacente Sa se verifice daca graful este regulat Sa se determine daca graful este complet

Componente conexe
Fie G=(V, E) un graf neorientat, unde V are n elemente (n noduri) si E are m elemente (m muchii). Definitie: G1=(V1, E1)este o componenta conexa daca: - pentru orice pereche x,y de noduri din V1 exista un lant de la x la y (implicit si de la y la x) - nu exista alt subgraf al lui G, G2=(V2, E2) care sa indeplineasca prima conditie si care sa-l contina pe G1

7 5

Graful alaturat are doua componente conexe: - subgraful care contine nodurile: 12345 - subgraful care contine nodurile: 67

2 3 4

Observatie: subgraful 1, 2, 3, 4 nu este componenta conexa pentru ( chiar daca pentru orice pereche x,y de noduri exista un lant de la x la y) deoarece exista subgraful 1, 2, 3, 4, 5 care il contine si indeplineste aceeasi conditie. Definitie: Un graf G=(V, E)este conex daca pentru orice pereche x,y de noduri din V exista un lant de la x la y (implicit si de la y la x). Observatii: - Un graf este conex daca admite o singura componenta conexa. - Graful anterior nu este conex pentru ca admite doua componente conexe Graful urmator este conex:
1 6 7 5 3 4

Probleme: 1. 1. Fiind dat un graf memorat prin intermediul matricei de adiacenta sa se determine daca graful este conex. 2. 2. Fiind dat un graf memorat prin intermediul matricei de adiacenta si un nod k sa se determine componenta conexa careia ii apartine nodul k 3. 3. Sa se afiseze toate componentele conexe ale unui graf neorientat Indicatii : -In vectorul viz se incarca numarul componentei conexe astfel pentru graful urmator, vectorul viz va retine:

viz=[1,1,1,1,2,1,2]. -Numarul de componente conexe este 2. -Se afiseaza componentele cu numarul componentei conexe egal cu 1: 1,2,3,4,6 -Se afiseaza componentele cu numarul componentei conexe egal cu 2: 5, 7
1

7 6

2 3 4

-Incarcarea in viz se realizeaza prin parcurgere df pornind de la fiecare nod -se porneste de la 1, se parcurge df si se incarca in viz valoarea 1 pt nodurile 1, 2, 3, 4, 6. Viz devine: 1,1,1,1,0,1,0 -se porneste in continuare de la primul nod nevizitat, adica 5 si se incarca numarul celei de a doa componente, adica 2 Viz devine: 1,1,1,1,2,1,2 -Nu mai sunt noduri nevizitate si algoritmul se incheie. Iata o solutie: #include<fstream.h> #include<conio.h> int a[20][20],n,m,viz[100],gasit; int nrc; //pastreaza numarul componentei conexe void dfmr(int nod) { viz[nod]=nrc; //se incarca numarul componentei for(int k=1;k<=n;k++) if(a[nod][k]==1&&viz[k]==0) dfmr(k); } void main() {int x,y,j; fstream f;

clrscr(); f.open("muchii.txt",ios::in); //memorare matrice de adiacenta if(f) cout<<"ok!"<<endl; else cout<<"eroare la deschidere de fisier!"; f>>n>>m; for(int i=1;i<=m;i++) {f>>x>>y; a[x][y]=a[y][x]=1;} cout<<endl<<"matricea de adiacente"<<endl; for(i=1;i<=n;i++) {for(j=1;j<=n;j++) cout<<a[i][j]<<" "; cout<<endl;} for(int nod=1;nod<=n;nod++) if(viz[nod]==0) //se incearca parcurgerea numai daca un nod nu a fost deja parcurs {nrc++; dfmr(nod);} cout<<endl<<"vectorul viz "<<endl; for(i=1;i<=n;i++) cout<<viz[i]<<" "; cout<<endl<<"Componentele conexe :"<<endl; for(i=1;i<=nrc;i++) {cout<<endl<<"componenta "<<i<<endl; for(j=1;j<=n;j++) if(viz[j]==i) cout<<j<<" "; } getch();}

S-ar putea să vă placă și