Grafuri și arbori - terminologie, proprietăți și reprezentare
Ideile de bază pe scurt și, unde există, exercițiile din subiectele de BAC care le verifică. Lecția completă, animată, cu grile și exerciții corectate, e în aplicația Tomomi.
Pe scurt
Sintaxă: matricea de adiacență
Pentru muchia x y într-un graf neorientat marchezi ambele celule oglindă; gradul unui nod este numărul de 1 de pe linia sa:
a[x][y] = 1;
a[y][x] = 1;
// gradul nodului i:
int g = 0;
for (int j = 0; j < n; j++) {
if (a[i][j] == 1) {
g++;
}
}Idee: cele două reprezentări
Un graf se memorează fie prin matricea de adiacență (a[i][j] = 1 dacă există muchie, simplu de interogat, dar ocupă celule), fie prin liste de adiacență (pentru fiecare nod, lista vecinilor lui, economică atunci când muchiile sunt puține).
Capcana: gradul numără toată linia
Gradul unui nod numără TOATE valorile de 1 de pe linia sa, nu doar jumătate (j < i greșește). Și nu uita: a[i][i] = 0, diagonala nu contribuie la grad.
Idee: lanț, ciclu, lungime
Un lanț este o succesiune de noduri adiacente două câte două; este elementar dacă niciun nod nu se repetă. Un ciclu este un lanț care se închide în nodul de plecare. Lungimea se numără mereu în MUCHII, deci un lanț cu 4 noduri are lungimea 3.
Idee: conex, complet, hamiltonian, eulerian
Conex: între oricare două noduri există lanț. Complet: oricare două noduri distincte sunt unite de o muchie, deci are muchii. Hamiltonian: are un ciclu prin toate NODURILE o dată. Eulerian: are un ciclu prin toate MUCHIILE o dată.
Șablon: gradele într-un graf orientat
Gradul extern se citește pe LINIE, gradul intern pe COLOANĂ:
int outDeg = 0;
int inDeg = 0;
for (int j = 0; j < n; j++) {
if (a[i][j] == 1) {
outDeg++;
}
if (a[j][i] == 1) {
inDeg++;
}
}Capcana: matricea orientată nu e simetrică
La graful orientat, a[i][j] = 1 înseamnă DOAR arcul de la i la j; a[j][i] poate fi 0. De aceea fiecare nod are două grade, iar suma gradelor externe este egală cu suma gradelor interne, ambele fiind numărul de arce.
Șablon: citirea vectorului de tați
Rădăcina, fiii și frunzele se obțin toate din același tablou t:
// radacina: nodul cu t[i] = 0
for (int i = 1; i <= n; i++) {
if (t[i] == 0) {
root = i;
}
}
// fiii nodului x: pozitiile j cu t[j] = x
for (int j = 1; j <= n; j++) {
if (t[j] == x) {
cout << j << " ";
}
}Idee: rudele unui nod
Părintele este ascendentul direct, fiii sunt descendenții direcți, iar nodurile cu același părinte sunt frați. Un ascendent este orice nod de pe drumul până la rădăcină, un descendent este orice nod aflat dedesubt, iar un nod fără fii se numește nod terminal sau frunză.
Capcana: poziție față de valoare
În vectorul de tați, t[i] este PĂRINTELE nodului i. Fiii lui i NU se citesc din t[i], ci se caută printre valori: sunt pozițiile j cu t[j] = i. La fel, o frunză este un nod care nu apare deloc ca valoare în t.
Idee: cele trei reprezentări ale unui arbore
Vectorul de tați: t[i] este părintele lui i, rădăcina are t[i] = 0; ocupă n valori și dă părintele instant. Listele de descendenți: pentru fiecare nod, lista fiilor lui; dau fiii instant. Matricea de adiacență: a[i][j] = 1 dacă i și j sunt legate, simetrică, ocupă valori și răspunde instant la „sunt vecine?”. Aceeași informație, trei feluri de a o ține minte.
Din subiectele de BAC
Exerciții reale din subiectele anilor trecuți. Încearcă-le singur înainte să deschizi rezolvarea.
Un graf orientat fără circuite are 10 vârfuri. Indicați numărul maxim de arce ale grafului.
a. 10
b. 45
c. 50
d. 90
Vezi rezolvarea
Într-un graf orientat fără circuite vârfurile pot fi numerotate astfel încât orice arc să meargă de la un vârf cu număr mai mic la unul cu număr mai mare (o sortare topologică). Atunci pentru fiecare pereche de vârfuri există cel mult un arc, iar numărul maxim de arce este numărul de perechi:
Răspunsul corect este litera b. Varianta d, , este numărul maxim de arce ale unui graf orientat oarecare cu 10 vârfuri - dar acolo ambele arce dintre două vârfuri ar forma un circuit de lungime 2, interzis aici.
Într-un graf neorientat, cu 10 muchii, două noduri au gradul 0, șase noduri au grade impare, iar celelalte noduri au grade pare, nenule. Indicați numărul maxim de noduri ale grafului.
a. 17 b. 15 c. 12 d. 10
Vezi rezolvarea
Suma gradelor într-un graf neorientat este dublul numărului de muchii: .
Pentru a maximiza numărul de noduri, fiecare nod trebuie să consume cât mai puțin din suma gradelor:
- cele 2 noduri de grad 0 nu consumă nimic;
- cele 6 noduri cu grad impar au gradul minim 1, consumând în total 6;
- rămân pentru nodurile cu grad par nenul, deci cu gradul minim 2: cel mult noduri.
Numărul maxim de noduri este , litera b.
Indicați un vector de „tați” corespunzător unui arbore cu 7 noduri, în care cel puțin unul dintre noduri are trei ascendenți.
a. 0,1,2,1,1,1,2
b. 3,0,2,1,3,2,1
c. 4,3,0,3,4,4,3
d. 5,4,3,0,2,3,4
Vezi rezolvarea
La varianta b, vectorul de tați (3,0,2,1,3,2,1) descrie arborele cu rădăcina în nodul (singurul cu tatăl ):
- tatăl nodului este , tatăl nodului este ;
- tatăl nodului este .
Lanțul de ascendenți ai nodului este: , apoi , apoi (rădăcina), deci nodul are exact trei ascendenți.
La varianta a, adâncimea maximă este 2 (niciun nod cu trei strămoși), iar variantele c și d nu oferă un nod cu trei ascendenți în structura de arbore cerută. Răspunsul corect este b.