Documente Academic
Documente Profesional
Documente Cultură
PARCURGEREA GRAFURILOR
Capitolul 3
1. Noiunile de lan i ciclu
Observaie: Dac vrfurile z1, z2,......,zk sunt distincte dou cte dou, lanul se numete elementar;
n caz contrar, lanul este ne-elementar.
Exemplu: Lanul L4 din exemplul anterior este elementar, pentru c nici un vrf nu apare de dou ori.
La fel, lanul L1. n schimb, lanurile L2 i L3 sunt ne-elementare: n L2 se repet vrful 2, iar n L3 se
repet vrful 3.
Definiie: Se numete ciclu ntr-un graf, un lan L=(z1, z2,........zk) cu proprietatea c z1=zk i muchiile
[z1,z2], [z2,z3],........,[zk-1,zk] sunt distincte dou cte dou.
Exemplu: n graful din figura de mai sus, C1=(3,4,5,3,7,6,1,2,3), C2=(1,2,3,7,6,1), C3=(3,5,4,9,3) sunt
cicluri. De exemplu, C3 este ciclu, deoarece traseul pe care l descrie pornete din vrful 3 i ajunge tot
n vrful 3, i n plus muchiile [3,5], [5,4], [4,9] i [9,3] sunt distincte dou cte dou (nu apare aceeai
muchie de mai multe ori).
Observaie: Dac ntr-un ciclu, toate vrfurile cu excepia primului i a ultimului sunt distincte dou
cte dou, atunci ciclul se numete elementar; n caz contrar, el este ne-elementar.
Exemplu: Ciclurile C2 i C3 din exemplul anterior sunt elementare, iar C1 este ne-elementar (n C1
vrful 3 apare i ca vrf intermediar, adic traseul descris mai trece odat prin vrful 3 pe lng faptul
c pornete din el i se ntoarce tot n el).
Aplicatie: Aciclicitate
S se verifice dac un graf neorientat, dat prin lista muchiilor sale, conine sau nu cicluri.
Reamintim c un graf care nu conine cicluri se numete aciclic. Pentru reconstituirea grafului se
folosete un vector g ncrcat iniial cu vrfurile 1,2..,n ale grafului. Adugarea unei muchii [x,y] n
graf presupune testarea valorilor g[x] i g[y]. Dac ele sunt distincte, atunci adugarea acestei muchii
nu va produce nici-un ciclu i ea va fi urmat de actualizarea tuturor componentelor lui g pentru toate
vrfurile cu valoarea g[y]. Dac valorile g[x] i g[y] coincid, atunci adugarea muchiei [x,y] duce la
formarea unui ciclu. Cele m muchii ale grafului sunt memorate n vectorul u al muchiilor. Pentru
testarea aciclitii s-a scris o funcie cu rezultat de tip ntreg.
Suport de curs pentru unitatea de nvare
2 Informatic Teorie clasa a XI-a
PARCURGEREA GRAFURILOR
int Aciclic(MUCHIE u[M],int n,int m)
{
int i,j,v,w,g[M];
for(i=1;i<=n;i++) g[i]=i; //initial fiecare varf este marcat
//separat, coresp. unui graf format din n varfuri izolate
for(i=1;i<=m;i++) //reconstituim graful muchie cu muchie
{
v=g[u[i].y]; w=g[u[i].x]; //marcajele extremitatilor muchiei i
if(v==w) return 0;//au acelasi marcaj,fac parte dintr-un ciclu
for(j=1;j<=n;j++) //reunesc marcajele
if(g[j]==v) g[j]=w;
}
return 1;
}
Fiind dat un graf neorientat G=(X,U) prin matricea de adiacen, se cere s se determine toate
perechile de vrfuri ntre care exist cel puin un lan. Pentru rezolvarea acestei probleme se poate
folosi algoritmul Roy-Warshall care, plecnd de la matricea de adiacen a unui graf construiete
matricea lanurilor definit astfel:
Practic, un element a[i][j] al matricei de adiacen devine 1 dac exist un vrf k astfel nct a[i][k]=1
(exist lan de la i la k) i a[k][j]=1 (exist lan de la k la j). Evident, n acest situaie lanul poate fi
extins de la vrful i la vrful j. Funcia care transform matricea de adiacen n matricea lanurilor
conform algoritmului Roy-Warshall este urmtoarea:
void Roy_Warshall()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(!a[i][j]) a[i][j]=a[i][k]*a[k][j];
}
Spre deosebire de cazul grafurilor neorientate, un lan ntr-un graf orientat se definete ca un
ir de arce L=[u1,u2,......,uk] cu proprietatea c oricare dou arce vecine ui,ui+1 au o extremitate
comun. n definirea unui lan nu se ine cont de orientarea arcelor.
Exemplu:
Pentru graful din figura alturat putem defini lanurile:
L1=(u1, u1 u2,u3) i L2=(u1,u4,u5,u3) ambele de extremiti 1 i
4. 2
Exemplu:
n exemplul anterior D2 este drum elementar iar D1 nu este elementar.
Dac D=(xi0,.....,xim) este un drum cu xi0=xim i arcele (xi0,xi1),......,(xim-1,xim) sunt distincte,
drumul D se numete circuit.
Dac toate vrfurile circuitului cu excepia primului i ultimului nod sunt distincte dou cte
dou circuitul se numete elementar.
2
u1 Exemplu:
u2
Pentru graful din figura alturat D1=(1,2,3,4,5,6,4,1),
D2=(1,2,3,4,1) i D3=(4,5,6,4) sunt circuite dar numai D2 i
1 3
D3 sunt elementare.
u4
u3
4
u7
u5
6
5
u6
Se numete matrice a drumurilor asociat grafului orientat G=(X,U), matricea D=(dij)nxn dat prin:
Se observ c matricea drumurilor are practic aceeai semnificaie ca matricea lanurilor pentru
grafurile neorientate: d[i,j]=1 semnific existena unui traseu (o deplasare posibil folosind arce din
graf) de la punctul i pn la punctul j. Pentru determinarea matricii drumurilor se folosete matricea de
adiacen a grafului i algoritmul Roy-Warshall prezentat la grafurile neorientate.
void RW()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(!a[i,j]) a[i][j]=a[i][k]*a[k][j];
}
Observaii:
1. Dac d[i][i]=1 nseamn c exist un circuit care trece prin nodul i.
2. Dac linia i i coloana i din matricea drumurilor conin numai elemente nule deducem c i este
un vrf izolat (nu exist drumuri care s duc la i i nici care s plece din i).
3. Pentru a verifica dac un nod i este nod iniial (sau nod surs), adic dac exist drumuri de
la el la oricare alt nod, este suficient s verificm dac n matricea drumurilor toate elementele
liniei i (exceptnd eventual cel din coloana i) sunt egale cu 1.
4. Pentru a verifica dac un nod i este nod final (sau nod destinaie), adic dac exist drumuri
de la oricare alt vrf la vrful i, este sufucient s verificm dac n matricea drumurilor toate
elementele coloanei i (exceptnd eventual cel de pe linia i) sunt egale cu 1.
Suport de curs pentru unitatea de nvare
4 Informatic Teorie clasa a XI-a
PARCURGEREA GRAFURILOR
5. Parcurgerea grafurilor
Prin parcurgerea unui graf se nelege examinarea n mod sistematic a nodurilor sale, plecnd
dintr-un nod i, astfel nct fiecare nod accesibil din i pe muchii adiacente dou cte dou, s fie atins o
singur dat.
Trecerea de la un nod i la altul se face prin explorarea, ntr-o anumit ordine, a vecinilor lui i
(nodurile cu care este adiacent). Aceast aciune se numete vizitare sau traversare a vrfurilor
grafului, scopul fiind prelucrarea informaiilor asociate nodului. Graful este o structur neliniar de
organizare a datelor, iar rolul traversrii sale poate fi i determinarea unei aranjri liniare a nodurilor, n
vederea trecerii de la unul la altul. Exist mai multe metode de parcurgere a grafurilor neorientate, cele
mai folosite fiind metodele BF i DF.
Pentru construcia practic a algoritmului, n vederea alegerii la un moment dat, dintre toi
vecinii unui vrf, pe acela nevizitat nc i care ndeplinete condiia impus, vom folosi un vector VIZ
cu n componente definite astfel:
Prin acest metod se parcurge graful n adncime ori de cte ori acest lucru este posibil.
Parcurgerea ncepe cu un vrf iniial dat i i continu cu primul dintre vecinii si nevizitai, fie acesta
vrful j. n continuare se procedeaz n mod similar cu vrful j, trecndu-se la primul dintre vecinii si
nevizitai nc, etc. Altfel spus, odat ajuni ntr-un vrf, alegem n continuare primul dintre vrfurile
adiacente nealese nc i
continum parcurgerea.
Cnd acest lucru nu mai
este posibil, facem un
pas napoi spre vrful
vizitat ultima dat i
plecm, dac este posibil,
spre un alt vecin. Ori de
cte ori nu putem nainta,
facem un pas napoi, deci
avem de a face cu un
algoritm backtracking.
Suport de curs pentru unitatea de nvare
6 Informatic Teorie clasa a XI-a
PARCURGEREA GRAFURILOR
Pentru graful din figura anterioar i vrful de plecare
i=1, ordinea de parcurgere DF a vrfurilor este: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
Pentru a marca vrfurile vizitate vom folosi vectorul VIZ cu aceeai semnificaie ca la metoda BF.
#include<stdio.h>
#define N 30
#define M 60
typedef unsigned char tip;
void citire(tip a[N][N],int &n,int &v)
{
int k,x,y,m; ifstream f( graf.txt) ;
f>>n>>m;
for(k=1;k<=m;k++)
{
f>>x>>y;
a[x][y]=a[y][x]=1;
}
f>>v; f.close();
}
void afisare(tip a[N][N],int n)
{
int i,j;
cout<<"\n\n Matricea de adiacenta a grafului:\n\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++) cout<<a[i][j]<< ;
cout<<"\n";
}
cout<<"\n";
}
void DF(tip a[N][N],int n,tip viz[N],int v)
{
int j;
cout<<"%d ",v); viz[v]=1;
for(j=1;j<=n;j++)
if(a[v][j] && !viz[j]) DF(a,n,viz,j);
//primul vecin al lui v nevizitat inca
}
void main()
{
tip a[N][N]={0},viz[N]={0}; int n,v;
citire(a,n,v); afisare(a,n);
cout<<"\n\nNodurile in ordine DF:\n\n"; DF(a,n,viz,v); cout<<"\n";
}