Sunteți pe pagina 1din 9

3. GRAFURI.

IMPLEMENTĂRI ÎN
LIMBAJUL PASCAL

Problema 1. Să se genereze reprezentarea unui graf dat prin listă de liste şi


să se vizualizeze structura prin parcurgere.

uses crt;
type
{lista vecinilor}
ptnod1=^nod1;
nod1=record
vecin:byte;
leg1:ptnod1;
end;

{lista L_nod, a nodurilor grafului}


ptlnod=^lnod;
lnod=record
nod:byte;
ptvecini:ptnod1;
leg:ptlnod;
end;

var
prim,actual,ultim:ptlnod;
vp,va,vu:ptnod1;
inf,n,i,j,m:byte;
begin
clrscr;
write('Numarul de noduri:');
readln(n);
prim:=nil; ultim:=nil;
{crearea listei L_nod}
for i:=1 to n do
begin
new(actual);
actual^.nod:=i;
actual^.leg:=nil;
{crearea listei vecinilor}
write('Numarul de vecini ai nodului ',i,':');
readln(m);
vp:=nil;va:=nil;
Programarea calculatoarelor. Aplicaţii

for j:=1 to m do
begin
new(va);
write('Vecinul ',j,':');
readln(inf);
va^.vecin:=inf;
va^.leg1:=nil;
if vp=nil then
begin
vp:=va;vu:=va;
end
else
begin
vu^.leg1:=va;vu:=va;
end;
end;
actual^.ptvecini:=vp;
if prim=nil then
begin
prim:=actual;
ultim:=actual;
end
else
begin
ultim^.leg:=actual;
ultim:=actual;
end;
end;
{scrierea grafului nod-vecin}
writeln;
actual:=prim;
while actual<>nil do
begin
write('Nodul ',actual^.nod,' are vecinii:');
vp:=actual^.ptvecini;
while vp<>nil do
begin
write(vp^.vecin,' ');
vp:=vp^.leg1;
end;
writeln;
actual:=actual^.leg;
end;
readln;
end.

Problema 2. Scrieţi un program Pascal pentru implementarea celei de-a doua


variante de parcurgere DF aplicată unui graf G=(V,E), V = n (Vezi cartea
Programarea calculatoarelor. Tehnica programării în limbajul Pascal).

Structurile de date utilizate pentru rezolvarea problemei sunt:


• o structură de tip stivă, S, reprezentată printr-o listă dinamică simplu
înlănţuită.
• un vector c cu n componente, în care:
1, dacă i a fost vizitat
ci = 
0, altfel
Grafuri. Implementări în limbajul Pascal

Componentele vectorului c vor fi iniţializate cu valoarea 0.


• o funcţie urm(i) care determină primul dintre vecinii vârfului argument incă
nevizitat. În momentul vizitării unui vârf, operaţie însoţită de afişarea vârfului
respectiv, componenta corespunzătoare lui din vectorul c este modificată (devine
egală cu 1).
Vârfurile grafului sunt numerotate de la 1 la n, vârful iniţial este vârful 1.
Graful este reprezentat prin matricea de adiacenţă. Accesul la stiva S este realizat
prin intermediul procedurilor push şi pop pentru introducerea, respectiv extragerea
unui element.

uses crt;
type
ptstiva=^stiva;
stiva=record
inf:byte;
leg:ptstiva;
end;
var
prim:ptstiva;
c:array[1..20] of byte;
a:array[1..20,1..20] of byte;
i,j,k,n:byte;
gata:boolean;
procedure push(var p:ptstiva;i:byte);
var a:ptstiva;
begin
new(a);
a^.inf:=i;
a^.leg:=p;
p:=a;
end;
procedure pop(var p:ptstiva;var i:byte);
var a:ptstiva;
begin
if p<>nil then
begin
i:=p^.inf;
a:=p;
p:=p^.leg;
dispose(a);
end;
end;
function urm(i:byte):integer;
var k:byte;
gasit:boolean;
begin
k:=1;
gasit:=false;
while(k<=n)and not gasit do
if (a[i,k]=1) and (c[k]=0)then
begin
gasit:=true; urm:=k;
end
else inc(k);
Programarea calculatoarelor. Aplicaţii

if not gasit then urm:=0;


end;
begin {program principal}
clrscr;
write('Numarul de varfuri:');
readln(n);
writeln('Matricea de adiacenta');
for i:=1 to n do
for j:=1 to n do
begin
write('a[',i,',',j,']=');
readln(a[i,j]);
end;
for i:=2 to n do
c[i]:=0;
readln;
clrscr;
writeln('Incepem parcurgerea de la nodul 1');
c[1]:=1;
prim:=nil;
write(1,' ');
i:=1;
push(prim,i);
gata:=false;
repeat
k:=urm(i);
if k=0 then
if prim=nil then
gata:=true
else pop(prim,i)
else begin
write(k,' ');
c[k]:=1;
push(prim,k);
i:=k;
end;
until gata;
readln;
end.

Problema 3. Scrieţi programul Pascal pentru determinarea componentei


conexe care conţine un vârf dat, într-un graf G=(V,E), V = n .

În continuare se presupune graful reprezentat în formă tabelară. Procedurile


utilizate efectuează următoarele operaţii:
- procedure copiaza(var v1,v2:vector;n:integer): copiază vectorul v1 de
dimensiune n în vectorul v2;
- procedure adauga(var v:vector;var n:integer;el:integer): extinde vectorul cu n
componente v prin adaugarea elementului el ca a n+1-a componentă dacă
valoarea el nu se regăseşte printre componentele lui v;
- procedure mcopiaza(var v1,v2:mat;n:integer): copiază matricea v1 cu n linii şi 2
coloane în matricea v2 (perechile de componente corespunzătoare fiecărei linii a
matricei v1 reprezintă muchii ale grafului);
Grafuri. Implementări în limbajul Pascal

- procedure madauga(var v:mat;var n:integer;el1,el2:integer): extinde matricea v


prin adaugarea elementului liniei suplimentare (el1, el2) reprezentând o muchie a
grafului dacă aceasta nu este deja reprezentată în v;
Variabilele globale folosite au următoarea semnificaţie:
- n,m: numărul vârfurilor, respectiv al muchiilor grafului;
- v0,v : la fiecare iteraţie, conţin componentele mulţimilor Vi-1 şi respectiv Vi;
- e0,e: la fiecare iteraţie, conţin componentele mulţimilor Ei-1 şi respectiv Ei;
- dv,dv0: dimensiunile vectorilor v, respectiv v0;
- de,de0: numărul liniilor matricelor e, respectiv e0.

uses crt;
type
vector=array[1..20]of integer;
mat=array[1..200,1..2] of integer;
var a,e,e0:mat;
v,v0:vector;
i,j,k,m,n,l:integer;
dv,dv0,de,de0:integer;
gata:boolean;
procedure copiaza(var v1,v2:vector;n:integer);
var i:byte;
begin
for i:=1 to n do
v2[i]:=v1[i];
end;
procedure adauga(var v:vector;var n:integer;el:integer);
var i:integer;
adaug:boolean;
begin
i:=1;
adaug:=true;
while adaug and(i<=n) do
if el=v[i] then
daug:=false
else i:=i+1;
if adaug then
begin
n:=n+1;
v[n]:=el;
end;
end;
procedure mcopiaza(var v1,v2:mat;n:integer);
var i:byte;
begin
for i:=1 to n do
begin
v2[i,1]:=v1[i,1];
v2[i,2]:=v1[i,2];
end;
end;
procedure madauga(var v:mat;var n:integer;el1,el2:integer);
var i:integer;
adaug:boolean;
begin
Programarea calculatoarelor. Aplicaţii

i:=1;adaug:=true;
while adaug and(i<=n) do
if ((el1=v[i,1])and(el2=v[i,2])) or
((el1=v[i,2])and(el2=v[i,1]))
then adaug:=false
else i:=i+1;
if adaug then
begin
n:=n+1;
v[n,1]:=el1;
v[n,2]:=el2;
end;
end;
begin {program principal}
clrscr;
write('Numarul de varfuri:');
readln(n);
write('Numarul de muchii:');
readln(m);
for i:=1 to m do
for j:=1 to 2 do
begin
write('a[',i,',',j,']=');
readln(a[i,j]);
end;
write('Varful pentru care se det. comp. conexa:');
readln(k);
v0[1]:=k;
dv:=1;
dv0:=1;
de:=0;
de0:=0;
v[1]:=k;
gata:=false;
repeat
for l:=1 to dv0 do
for j:=1 to m do
if (a[j,1]=v0[l])then
begin
madauga(e,de,a[j,1],a[j,2]);
adauga(v,dv,a[j,2])
end
else if (a[j,2]=v0[l])then
begin
adauga(v,dv,a[j,1]);
madauga(e,de,a[j,2],a[j,1]);
end;
if (dv0=dv)and(de0=de) then
gata:=true
else begin
copiaza(v,v0,dv);
mcopiaza(e,e0,de);
dv0:=dv;
de0:=de;
end;
until (gata);
for i:=1 to dv do
write(v[i],' ');
writeln;
for i:=1 to de do
writeln(e[i,1],'---->',e[i,2]);
Grafuri. Implementări în limbajul Pascal

readln;
end.

Problema 4. Să se realizeze implementarea Pascal pentru algoritmul Yen.


Graful este repezentat prin matricea ponderilor. Valoarea ponderii 10000 semnifică
absenţa muchiei.
uses crt;
var
d,w:array[1..20,1..20] of real;
k,i,j,n,l,j0:byte;
v,b:array[1..20] of real;
min:real;

function minim(x,y:real):real;
begin
if x<y then minim:=x
else minim:=y;
end;
begin
clrscr;
write('Numarul de varfuri ale grafului:');
readln(n);
writeln('Matricea ponderilor:');
for i:=1 to n do
for j:=1 to n do
if i<>j then
begin
write('w[',i,',',j,']=');
readln(w[i,j]);
d[i,j]:=w[i,j];
end
else begin
w[i,j]:=10000;
d[i,j]:=10000;
end;
write('Varful dorit:');
readln(k);
for i:=1 to n do v[i]:=1;
v[k]:=0;b[k]:=0;
for i:=1 to n do
begin
min:=10000;
for j:=1 to n do
if (v[j]=1)and(d[k,j]<min)then
begin
j0:=j;
min:=d[k,j];
end;
for j:=1 to n do
d[k,j]:=minim(d[k,j],d[k,j0]+d[j0,j]);
v[j0]:=0;
b[j0]:=d[k,j0];
end;
writeln('Distantele minime de la ',k,' la celelalte varfuri ');
for i:=1 to n do
begin
write(k,'---->',i);
writeln(':',b[i]);
end;
readln;
Programarea calculatoarelor. Aplicaţii

end.

Exerciţii

1. Să se scrie un program pentru citirea matricei de adiacenţă a unui graf,


generarea reprezentării tabelare şi obţinerea listei vecinilor fiecărui vârf al grafului.
2. Să se scrie un program pentru parcurgerea BF în prima variantă de
prezentare (a se vedea Capitolul 3 din Programarea calculatoarelor. Tehnica
programării în limbajul PascalI).
3. Să se scrie un program pentru implementarea parcurgerii BF aplicată
unui graf reprezentat prin liste.
4. Să se scrie un program pentru implementarea parcurgerii DF în prima
variantă de prezentare (a se vedea Capitolul 3 din Programarea calculatoarelor.
Tehnica programării în limbajul PascalI).
5. Să se scrie un program pentru implementarea parcurgerii DF aplicată
unui graf reprezentat prin liste.
6. Să se scrie un program pentru verificarea faptului că o secvenţă de
vârfuri într-un graf este un drum.
7. Să se scrie o procedură pentru determinarea tuturor subdrumurilor
elementare ale unui drum dat.
8. Să se scrie o procedură pentru verificarea conexităţii unui graf pe baza
parcurgerii BF.
9. Să se scrie o procedură pentru verificarea conexităţii unui graf pe baza
parcurgerii DF.
10. Să se scrie o procedură pentru calculul matricei existenţei drumurilor
(1) ( 2) ( n −1)
într-un graf cu n vârfuri, M = A ⊕ A ⊕ Κ ⊕ A .
11. Să se scrie o procedură pentru verificarea conexităţii unui graf pe baza
algoritmului Roy-Warshall.
12. Să se scrie un program pentru determinarea tuturor componentelor
conexe ale unui graf.
13. Să se scrie un program pentru implementarea algoritmului Dijkstra,
graful fiind conex şi reprezentat prin matricea ponderilor
14. Să se scrie un program pentru implementarea algoritmului Dijkstra,
graful fiind conex şi reprezentat prin liste.
15. Să se scrie un program pentru determinarea într-un graf ponderat conex a
perechilor de vârfuri (u, v) cu proprietatea că D(u,v)= max{D(x,y)/x,y∈V, x≠y}.
16. Să se scrie un program pentru determinarea într-un graf ponderat conex a
perechilor de vârfuri (u, v) cu proprietatea că D(u,v)= min{D(x,y)/x,y∈V, x≠y}.
17. Modificaţi programul pentru algoritmul Dijkstra pentru calculul valorilor
D(u , v) = min{L{Γ), Γ ∈ D uv } şi a câte unui u-v drum Γ astfel încât L( Γ )=D(u,v),
pentru toate perechile de vârfuri distincte u,v ale unui graf ponderat conex.
18. Propuneţi o variantă a algoritmului Dijkstra pentru calculul valorilor
Q( v 0 , v} = max{L(Γ), Γ ∈ D v0 v } şi a câte unui v0-v drum Γ astfel încât
Grafuri. Implementări în limbajul Pascal

L( Γ )=Q(v0,v), pentru toţi v∈V\{v0} unde v0 este un vârf fixat al unui graf ponderat
conex.

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