Documente Academic
Documente Profesional
Documente Cultură
4
Matrice de adiacen
Liste de adiacen
List de muchii/arce
Construcia din lista de muchii
//neorientat
l[y].push_back(x);
}
for(i=1;i<=n;i++){
cout<<i<<": ";
for(j=0;j<l[i].size();j++)
cout<<l[i][j]<<" ";
cout<<endl;
}
}
Liste implementate - pointeri
struct nod{ int info; type elem=^nod;
nod* urm;}; nod=record info:integer;
nod* l[100]; nod* p; urm:elem;
int n,m; end;
void citire(){ var l: array[1..100] of elem; var p:elem;
int i,x,y; var n,m:integer;
cin>>n>>m; procedure citire;
for(i=1;i<=n;i++) var i,x,y:integer;
l[i]=NULL; begin
for(i=1;i<=m;i++){ readln(n,m);
cin>>x>>y; for i:=1 to n do l[i]:=nil;
p=new nod; for i:=1 to m do
p->info=y; begin
p->urm=l[x]; readln(x,y);
l[x]=p; new(p);
//neorientat p^.info:=y;
p=new nod; p^.urm:=l[x];
p->info=x; l[x]:=p; {neorientat}
p->urm=l[y]; new(p); p^.info:=x;
l[y]=p; p^.urm:=l[y]; l[y]:=p;
} end;
//afisare liste {afisare liste}
for(i=1;i<=n;i++){ for i:=1 to n do
cout<<i<<": "; begin
p=l[i]; write(i,': ');
while(p!=NULL){ p:=l[i];
cout<<p->info<<" "; while p<>nil do
p=p->urm; begin
} write(p^.info,' ');
cout<<endl; p:=p^.urm;
} end;
}//citire writeln;
end;
end;
1
Vector tata
Lista de fii
3 5 9
(descendeni direci)
2 6 7 8
4
Dat un vector tata asociat unui arbore (arbore
genealogic) s se determine:
1) rdcina arborelui
2) frunzele arborelui
3) un lan de la un vrf dat la rdcin, afiat
direct i invers = ascendenii unui vrf (afiai
de la tat n sus/ de la rdcin n jos)
4) nivelul (generaia) fiecrui vrf n arbore i
nlimea arborelui (=numrul de generaii-1)
Rdcina este vrful care are tata egal cu 0
int radacina(){ function radacina:integer;
int i; var i:integer;
for(i=1;i<=n;i++) begin
if(tata[i]==0) for i:=1 to n do
return i; if tata[i]=0 then
return 0; radacina:=i;
} end;
Frunzele sunt vrfurile care nu apar n
vectorul tata
Varianta 1 Testm pentru fiecare vrf
i=1 n dac apare n vectorul tata
Complexitate?
void frunze1(){ procedure frunze1;
int i,j,ok; var i,j:integer;
for(i=1;i<=n;i++){ ok:boolean;
ok=1; begin
for(j=1;j<=n;j++) for i:=1 to n do
if (i==tata[j]) begin
ok=0; ok:=true;
if (ok) for j:=1 to n do
cout<<i<<' '; if i=tata[j] then
} ok:=false;
cout<<endl; if ok then
} write(i,' ');
end;
writeln;
end;
Varianta 1 Complexitate: O(n2)
Varianta 2 cu vector de apariii
Complexitate: O(n)
void frunze(){ procedure frunze;
int i; var i:integer;
int v[100]; v:array[1..100] of boolean;
begin
for(i=1;i<=n;i++) for i:=1 to n do
v[i]=0; v[i]:=true;
Idee:
- Marcm x i ascendenii lui x
- Urcm din y spre rdcin pn la primul vrf
marcat
Parcurgere = o modalitate prin care, plecnd
de la un vrf de start i mergnd pe
arce/muchii s ajungem la toate vrfurile
accesibile din s
Un vrf v este accesibil din s dac exist un
drum/lan de la s la v n G.
Idee: Dac
u este accesibil din s
uvE(G)
atunci v este accesibil din s.
(din aproape n aproape)
Parcurgerea n lime (BF = breadth first)
1 9
8
3 2
6
7
4 1
5
1 9
8
3 2
135926478
7
4 1
5
1 9
8
3 2
135926478
7
4 1
5
1 9 3 5 9
8
3 2
135926478
7
4 1
5
1 9 3 5 9
8
3 2
135926478
7
4 1
5
1 9 3 5 9
8
3 2
1 3 5 9 6 42 7 8
7
4 1
5
1 9 3 5 9
8
3 2 2 6
1 35926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6
135926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6
13 5926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6
135926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6
135 926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135 926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
1359 26478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
13592 6478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135926 478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
1359264 78
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135926478
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
13592647 8
7
4 1
5
1 9 3 5 9
8
3 2 2 6 4 7 8
135926478
Vrfurile vizitate trebuie marcate:
1 9 3 5 9
8
3 2 2 6 4 7 8
6
for(i=1;i<=n;i++) {
viz[i]=0;
Iniializri tata[i]=0;
d[i]=32000;
pentru i=1,n executa }
viz[i]0
tata[i]0
niv[i]
procedure BF(s) void bf(int s){
coada C ; int p,u,i,j;
adauga(s, C) p = u = 1; c[1]=s;
viz[s] 1 viz[s]=1;
cat timp C executa while(p<=u){
i extrage(C); i=c[p]; p=p+1;
afiseaza(i); cout<<i<<" ";
for(j=1;j<=n;j++)
pentru j vecin al lui i
if(a[i][j]==1)
daca viz[j]=0 atunci if(viz[j]==0){
adauga(j, C) u=u+1; c[u]=j;
viz[j] 1 viz[j]=1;
tata[j] i tata[j]=i;
d[j] d[i]+1 d[j]=d[i]+1;
}
}
}
procedure BF(s) void bf(int s){
coada C ; int p,u,i,j;
adauga(s, C) p = u = 1; c[1]=s;
viz[s] 1; niv[s] 0 viz[s]=1;
cat timp C executa while(p<=u){
i extrage(C); i=c[p]; p=p+1;
afiseaza(i); cout<<i<<" ";
for(j=1;j<=n;j++)
pentru j vecin al lui i
if(a[i][j]==1)
daca viz[j]=0 atunci if(viz[j]==0){
adauga(j, C) u=u+1; c[u]=j;
viz[j] 1 viz[j]=1;
tata[j] i tata[j]=i;
d[j] d[i]+1 d[j]=d[i]+1;
}
}
}
procedure BF(s) void bf(int s){
coada C ; int p,u,i,j;
adauga(s, C) p = u = 1; c[1]=s;
viz[s] 1; niv[s] 0 viz[s]=1;
cat timp C executa while(p<=u){
i extrage(C); i=c[p]; p=p+1;
afiseaza(i); cout<<i<<" ";
for(j=1;j<=n;j++)
pentru j vecin al lui i
if(a[i][j]==1)
daca viz[j]=0 atunci if(viz[j]==0){
adauga(j, C) u=u+1; c[u]=j;
viz[j] 1 viz[j]=1;
tata[j] i tata[j]=i;
d[j] d[i]+1 d[j]=d[i]+1;
}
}
}
procedure BF(s) void bf(int s){
coada C ; int p,u,i,j;
adauga(s, C) p = u = 1; c[1]=s;
viz[s] 1; niv[s] 0 viz[s]=1;
cat timp C executa while(p<=u){
i extrage(C); i=c[p]; p=p+1;
afiseaza(i); cout<<i<<" ";
for(j=1;j<=n;j++)
pentru j vecin al lui i
if(a[i][j]==1)
daca viz[j]=0 atunci if(viz[j]==0){
adauga(j, C) u=u+1; c[u]=j;
viz[j] 1 viz[j]=1;
tata[j] i tata[j]=i;
d[j] d[i]+1 d[j]=d[i]+1;
}
}
}
procedure BF(s) void bf(int s){
coada C ; int p,u,i,j;
adauga(s, C) p = u = 1; c[1]=s;
viz[s] 1; niv[s] 0 viz[s]=1;
cat timp C executa while(p<=u){
i extrage(C); i=c[p]; p=p+1;
afiseaza(i); cout<<i<<" ";
for(j=1;j<=n;j++)
pentru j vecin al lui i
if(a[i][j]==1)
daca viz[j]=0 atunci if(viz[j]==0){
adauga(j, C) u=u+1; c[u]=j;
viz[j] 1 viz[j]=1;
tata[j] i tata[j]=i;
d[j] d[i]+1 d[j]=d[i]+1;
}
}
}
procedure BF(s) void bf(int s){
coada C ; int p,u,i,j;
adauga(s, C) p = u = 1; c[1]=s;
viz[s] 1; niv[s] 0 viz[s]=1;
cat timp C executa while(p<=u){
i extrage(C); i=c[p]; p=p+1;
afiseaza(i); cout<<i<<" ";
for(j=1;j<=n;j++)
pentru j vecin al lui i
if(a[i][j]==1)
daca viz[j]=0 atunci if(viz[j]==0){
adauga(j, C) u=u+1; c[u]=j;
viz[j] 1 viz[j]=1;
tata[j] i tata[j]=i;
d[j] d[i]+1 d[j]=d[i]+1;
}
}
}
procedure BF(s) void bf(int s){
coada C ; int p,u,i,j;
adauga(s, C) p = u = 1; c[1]=s;
viz[s] 1; niv[s] 0 viz[s]=1;
cat timp C executa while(p<=u){
i extrage(C); i=c[p]; p=p+1;
afiseaza(i); cout<<i<<" ";
for(j=1;j<=n;j++)
pentru j vecin al lui i
if(a[i][j]==1)
daca viz[j]=0 atunci if(viz[j]==0){
adauga(j, C) u=u+1; c[u]=j;
viz[j] 1 viz[j]=1;
tata[j] i tata[j]=i;
niv[j] niv[i]+1 d[j]=d[i]+1;
}
}
}
int n;
int a[20][20];
int viz[20],tata[20],niv[20];
Iniializri int p,u,c[20];
ok=1;
for(i=1;i<=n;i++)
if(viz[i]==0)
ok=0;
Graful este conex dac, prin apelul parcurgerii din
vrful 1, sunt vizitate toate vrfurile
Graful este conex dac, prin apelul parcurgerii din
vrful 1, sunt vizitate toate vrfurile
bf(1);
ok=1;
for(i=1;i<=n;i++)
if(viz[i]==0)
ok=0;
if(ok==1)
cout<<conex;
else
cout<<neconex;
ntr-un grup de n persoane se cunosc
perechile de persoane care pot comunica
direct.
int main(){
int c[100],p,u;
f>>n>>r;
//construim matricea de adiacenta coresp. regulilor
for(i=1;i<=r;i++){
f>>x>>y;
a[x][y]=1;
gin[y]++;
}
//adaugam toate elementele cu grad intern 0 in coada c
p=0;u=-1;
for(i=1;i<=n;i++)
if(gin[i]==0)
{
u++; c[u]=i;
}
/*extragem un element de grad 0 din coada,
il adaugam in solutie si il eliminam din graf = scadem
cu 1 gradul intern al vecinilor sai;
Daca se obtin astfel varfuri de grad intern 0, le
adaugam in coada c */
while(p<=u){
x=c[p]; p++;
g<<x<<" ";
for(j=1;j<=n;j++)
if(a[x][j]==1){
gin[j]--;
if(gin[j]==0){
u++;
c[u]=j;
}
}
}
Tem
1. Modificai programul astfel nct graful s fie
memorat cu liste de adiacen
2. Modificai programul astfel nct s fie
detectat existena de circuite (date incorecte
dependene circulare)
Varianta 2 folosim parcurgerea n adncime DF
o Cu ct un vrf este finalizat (explorat cu toate
vrfurile accesibile din el) mai trziu n
parcurgerea DF, cu att el este mai la nceput n
ordonare (n sortarea topologic)
o Adugm ntr-o stiv vrfurile, pe msura terminrii
explorrii lor (adic explorrii tuturor vecinilor)
for(i=1;i<=n;i++)
if(viz[i]==0){
bf(i);
cout<<i<< ;
}
Idee modelm problema cu un graf
Traseul mesajului n fiecare component = lista de fii
pentru arborele bf memorat n vectorul tata (cte un
arbore pentru fiecare component)
1 9
8
3 2
6
7 1
4
5
1 9
8
3 2
6
7 1
4
5
3
1 9
8
3 2
6
7 1
4
5
3
1 9
8
2
3 2
6
7 1
4
5
3
1 9
8
2
3 2
6 9
7 1
4
5
3
1 9
8
2
3 2
6 9
4
7 1
4
5
3
1 9
8
2
3 2
6 9
8
7 1
4
5
3
1 9
8
2
3 2
6 9
8
7 1
4
5
3
1 9
8
2
3 2
6 9
8
7 1
4
5
3
1 9
8
2
3 2
6 9
4 7
8
7 1
4
5
3
1 9
8
2
3 2
6 9
4 7
8
7 1
4
5
3
1 9
8
2
3 2
6 9
4 7
8
7 1
4
5
3
1 9
8
2
3 2
6 9
4 7
8
7 1
4
5
3
1 9
8
2 6
3 2
6 9
4 7
8
7 1
4
5
3
1 9
8
2 6
3 2
6 9
4 7
8
7 1
4
5
3
1 9
8
2 6
3 2
6 9
4 7
8
7 1
4
5
3 5
1 9
8
2 6
3 2
6 9
4 7
8
7 1
4
5
3 5
1 9
8
2 6
3 2
6 9
4 7
8
7 1
4
5
3 5
1 9
8
2 6
3 2
6 9
4 7
8
void df(int i){
viz[i]=1;
cout<<i<<" ";
for(int j=1;j<=n ;j++)
if(a[i][j]==1)
if(viz[j]==0){
tata[j]=i;
df(j);
}
}
Apel:
df(s)
void df(int i){
viz[i]=1;
cout<<i<<" ";
for(int j=1;j<=n ;j++)
if(a[i][j]==1)
if(viz[j]==0){
tata[j]=i;
df(j);
}
}
Apel:
df(s)
void df(int i){
viz[i]=1;
cout<<i<<" ";
for(int j=1;j<=n ;j++)
if(a[i][j]==1)
if(viz[j]==0){
tata[j]=i;
df(j);
}
}
Apel:
df(s)
void df(int i){
viz[i]=1;
cout<<i<<" ";
for(int j=1;j<=n ;j++)
if(a[i][j]==1)
if(viz[j]==0){
tata[j]=i;
df(j);
}
}
Apel:
df(s)
void df(int i){
viz[i]=1;
cout<<i<<" ";
for(int j=1;j<=n ;j++)
if(a[i][j]==1)
if(viz[j]==0){
tata[j]=i;
df(j);
}
}
Apel:
df(s)
Dat un graf neorientat, s se verifice dac
graful conine cicluri i, n caz afirmativ,
s se afieze un ciclu al su
Marinescu Ghemeci Ruxandra