Parcurgerea grafurilor in adancime (depth first)

Parcurgerea unui graf in adancime se face prin utilizarea stivei (alocate implicit prin subprograme recursive).

Pentru fiecare varf se parcurge primul dintre vecinii lui neparcursi inca

Dupa vizitarea varfului initial x1, se exploreaza primul varf adiacent lui, fie acesta x2 , se trece apoi la primul varf adiacent cu x2 si care nu a fost parcurs inca , s.a.m.d.

Fiecare varf se parcurge cel mult odata

De exemplul pentru garful din figura de mai jos, se va proceda in felul urmator:

se porneste din varful 1, (se poate incepe de la oricare alt varf)

se exploreaza in continuare primul vecin al acestuia acestuia : varful 2,

se obtine 1,2

 

dupa care din 2 se exploreaza varful adiacent cu acesta si care nu a fost vizitat : 3.

se obtine 1,2,3

In continuare ar trebui sa se parcurga vecinul lui 3 nevizitat : 4

se obtine 1, 2, 3, 4

 

Pentru varful 4 ar trebui sa se parcurga primul sau vecin neparcurs (varful 1 dar acesta a fost deja parcurs. Nu mai avem ce vizita si se trece la nivelul anterior din stiva, la varful 3 :

1, 2, 3, 4 Se parcurge vecinul sau nevizitat, varful 5 .

SE obtine : 1, 2, 3, 4 , 5.

Varful 3 nu mai are vecini nevizitati si se trece pe nivelul anterior din stiva, varful 2 : 1, 2, 3, 4 , 5. Nici acesta nu mai are vecini nevizitati si se trece pe nivelul anterior la varful 1 : 1, 2, 3, 4 , 5. Cum nici acesta nu mai are vecini nevizitati se incheie algoritmul.

Varful 6 ramane nevizitat.

Algoritmul

-Graful se va memora utilizand matricea de adiacenta a[10][10]

-pentru a nu parcurge un varf de doua ori se va folosi un vector boolean viz care va retine :

- viz[k]=0 daca varful k nu a fost vizitat inca

- viz[k]=1 daca varful k a fost vizitat

-ca si la parcurgerea in latime vecinii unui varf se  cauta  pe linia acestui varf : daca a[nod][k]=1 inseamna ca varfurile nod si k sunt adiacente. Pentru ca varful k sa fie fie parcurs trebuie ca varful sa nu fi fost vizitat : viz[k]=0

 

#include<fstream.h>

#include<conio.h>

int a[20][20],n,m,viz[100],gasit;

 

void dfmr(int nod)

{

cout<<nod<<" ";

viz[nod]=1;

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("graf.txt",ios::in);

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]=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;}

cout<<endl<<"parcurgere in adancime incepand de la varful 1"<<endl;

dfmr(1);

 

getch();} 

 

Aplicatii :

1.Sa se parcurga graful in adancime pornind pe rand de la toate varfurile

2. Sa se determine daca pornind de la varful x se poate ajunge la varful y

3. Sa se determine daca se poate parcurge pornind de la un varf tot graful

 

Intr-un parc de distractii exista  Casa Labirint . Aceasta este formata din n incaperi intre care se gasesc culoare cu un singur sens de parcurgere. Se stie stie incaperea de la care se porneste.

a)      Sa se determine care sunt incaperile cu cele mai multe coridoare de legatura

b)      Care sunt incaperile in care traseul se blocheaza (fara iesire)

c)      Exista vreo incapere care sa aiba acces direct la toate celelalte