Tematică științifică · 5.1
Grafuri orientate și neorientate. Terminologie
Definiția grafului, graful neorientat și graful orientat, gradele nodurilor, metodele de reprezentare (matricea de adiacență, matricea de incidență, lista muchiilor, listele de adiacență), lanțul, ciclul, drumul și circuitul, graful parțial, subgraful și graful transpus, cu programe în C++.
Graful descrie o relație între
obiecte: nodurile sunt obiectele, iar perechile din U arată care obiecte sunt
în relație.
Numărul de noduri se numește ordinul grafului și se notează cu n:
n = card(X). Numărul de perechi din U se notează cu m: m = card(U).
Nodurile se etichetează, de regulă, cu numerele 1, 2, …, n.
Definiția grafului
Graful neorientat și graful orientat
Grafurile se clasifică după proprietatea de simetrie a mulțimii U:
Tipul grafului se alege după relația pe care o descrie. Legăturile prin cablu
dintre calculatoarele unei rețele se reprezintă printr-un graf neorientat: dacă
un cablu conectează calculatorul x cu calculatorul y, el conectează și
calculatorul y cu x. Rezultatele meciurilor dintr-un turneu se reprezintă
printr-un graf orientat, în care perechea (x, y) arată că echipa x a învins
echipa y; relația nu este simetrică, fiindcă din victoria lui x asupra lui
y nu rezultă victoria lui y asupra lui x.
În această lecție, o pereche neordonată se scrie între paranteze drepte,
[x, y], iar o pereche ordonată între paranteze rotunde, (x, y).
Graful neorientat
Terminologie
Elementele mulțimii U ale unui graf neorientat se numesc muchii. Muchia
care unește nodurile x și y se notează [x, y]; [x, y] și [y, x] sunt
aceeași muchie.
Graful neorientat G1 = (X1, U1) are:
X1 = {1, 2, 3, 4, 5, 6, 7}, deci ordinuln = 7;U1 = {[1,2], [1,3], [2,3], [3,4], [3,5], [4,5], [5,6]}, decim = 7.
În reprezentarea grafică, nodurile sunt cercuri, iar muchiile sunt segmente care unesc cercurile.
Noțiunile de bază, cu exemple din graful G1:
| Noțiunea | Definiția | Exemplu în G1 |
|---|---|---|
| noduri adiacente | două noduri care formează o muchie | 3 și 4 sunt adiacente; 1 și 4 nu sunt |
| nod incident cu o muchie | fiecare dintre cele două noduri ale muchiei | nodul 5 este incident cu [3,5], [4,5] și [5,6] |
| extremitățile unei muchii | cele două noduri pe care le unește muchia | extremitățile muchiei [2,3] sunt 2 și 3 |
| vecinii unui nod | nodurile adiacente cu el | vecinii nodului 3 sunt 1, 2, 4 și 5 |
| muchii incidente | două muchii care au o extremitate comună | [1,3] și [3,4], cu extremitatea comună 3 |
Gradul unui nod
În graful G1, gradele nodurilor sunt:
| Nodul | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
d(x) | 2 | 2 | 4 | 2 | 3 | 1 | 0 |
Nodul 6 este terminal, iar nodul 7 este izolat. Într-un graf cu n noduri,
gradul oricărui nod este cuprins între 0 și n − 1.
Suma gradelor. Pentru orice graf neorientat cu m muchii,
d(x1) + d(x2) + … + d(xn) = 2m
Fiecare muchie [x, y] adaugă o unitate la gradul lui x și o unitate la
gradul lui y, deci contribuie cu 2 la suma gradelor. În G1 suma gradelor este
2 + 2 + 4 + 2 + 3 + 1 + 0 = 14 = 2 · 7.
Din această relație rezultă că numărul nodurilor de grad impar este par:
suma gradelor este pară, deci termenii impari ai sumei sunt în număr par. În
G1, nodurile de grad impar sunt 5 și 6.
Graful orientat
Terminologie
Elementele mulțimii U ale unui graf orientat se numesc arce. Arcul de la
nodul x la nodul y se notează (x, y); (x, y) și (y, x) sunt arce
diferite. Arcul (x, y) pleacă din extremitatea inițială x și ajunge în
extremitatea finală y. Pentru graful orientat se folosește și denumirea
de digraf.
Graful orientat G2 = (X2, U2) are:
X2 = {1, 2, 3, 4, 5, 6};U2 = {(1,2), (1,4), (2,3), (3,1), (3,4), (4,5), (5,3), (5,6), (6,5)}, decim = 9.
În reprezentarea grafică, fiecare arc are o săgeată la extremitatea finală. Între nodurile 5 și 6 există două arce, câte unul în fiecare sens.
| Noțiunea | Definiția | Exemplu în G2 |
|---|---|---|
| noduri adiacente | două noduri legate printr-un arc, în oricare sens | 1 și 3 sunt adiacente, prin arcul (3,1) |
| nod incident cu un arc | fiecare dintre cele două extremități ale arcului | nodul 4 este incident cu (1,4), (3,4) și (4,5) |
| arce incidente | două arce care au o extremitate comună | (2,3) și (3,4), cu extremitatea comună 3 |
succesor al nodului x | un nod y pentru care (x, y) ∈ U | succesorii nodului 3 sunt 1 și 4 |
predecesor al nodului x | un nod y pentru care (y, x) ∈ U | predecesorii nodului 3 sunt 2 și 5 |
Gradul intern și gradul extern
Pentru un nod x al unui graf orientat se definesc:
| Nodul | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
d⁺(x) | 2 | 1 | 2 | 1 | 2 | 1 |
d⁻(x) | 1 | 1 | 2 | 2 | 2 | 1 |
Un nod cu d⁺(x) + d⁻(x) = 1 este nod terminal, iar un nod cu
d⁺(x) = d⁻(x) = 0 este nod izolat.
Suma gradelor. Arcul (x, y) se numără o singură dată în gradul extern al
lui x și o singură dată în gradul intern al lui y. De aici:
d⁺(x1) + … + d⁺(xn) = d⁻(x1) + … + d⁻(xn) = m
În G2 ambele sume sunt egale cu 9.
Numărul grafurilor cu n noduri
Între n noduri se pot forma n(n − 1)/2 perechi neordonate de noduri
distincte:
- într-un graf neorientat, fiecare pereche este sau nu muchie, deci se pot forma
2^(n(n−1)/2)grafuri neorientate cunnoduri date; - într-un graf orientat, pentru fiecare pereche
{x, y}există patru situații: niciun arc, arcul(x, y), arcul(y, x)sau amândouă arcele; se pot forma4^(n(n−1)/2)grafuri orientate.
Pentru n = 3 există 2³ = 8 grafuri neorientate și 4³ = 64 de grafuri
orientate.
Metode de reprezentare
Pentru a fi prelucrat într-un program, graful se memorează într-o structură de date. Metodele de reprezentare se deosebesc prin memoria ocupată și prin timpul în care se obțin informațiile despre graf.
Matricea de adiacență
Matricea de adiacență a unui graf cu n noduri este matricea pătratică
a, de ordinul n, cu elementele
a[i][j] = 1, dacă există muchia [i, j] (arcul (i, j))
a[i][j] = 0, altfel
Graful neorientat G1
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
|---|---|---|---|---|---|---|---|
| 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
| 3 | 1 | 1 | 0 | 1 | 1 | 0 | 0 |
| 4 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
| 5 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |
| 6 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| 7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Graful orientat G2
| 1 | 2 | 3 | 4 | 5 | 6 | |
|---|---|---|---|---|---|---|
| 1 | 0 | 1 | 0 | 1 | 0 | 0 |
| 2 | 0 | 0 | 1 | 0 | 0 | 0 |
| 3 | 1 | 0 | 0 | 1 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 1 | 0 |
| 5 | 0 | 0 | 1 | 0 | 0 | 1 |
| 6 | 0 | 0 | 0 | 0 | 1 | 0 |
Proprietățile matricei de adiacență:
- elementele de pe diagonala principală sunt 0, fiindcă o muchie unește două noduri distincte;
- la graful neorientat matricea este simetrică față de diagonala principală:
a[i][j] = a[j][i]; - la graful neorientat suma elementelor este
2m, iar la graful orientat estem.
Din matricea de adiacență se citesc direct următoarele informații:
| Informația | Graful neorientat | Graful orientat |
|---|---|---|
există muchia (arcul) de la i la j | a[i][j] = 1 | a[i][j] = 1 |
gradul nodului i | suma elementelor de pe linia i | d⁺(i) = suma de pe linia i; d⁻(i) = suma de pe coloana i |
vecinii (succesorii) lui i | coloanele j cu a[i][j] = 1 | succesorii: a[i][j] = 1; predecesorii: a[j][i] = 1 |
Reprezentarea ocupă n² elemente, oricâte muchii ar avea graful. Verificarea
existenței unei muchii se face printr-o singură accesare, dar determinarea
vecinilor unui nod cere parcurgerea întregii linii.
Matricea de incidență
Matricea de incidență a unui graf cu n noduri și m muchii are n linii,
câte una pentru fiecare nod, și m coloane, câte una pentru fiecare muchie sau
arc, numerotate în ordinea din mulțimea U:
graf neorientat: a[i][k] = 1, dacă nodul i este extremitate a muchiei k
a[i][k] = 0, altfel
graf orientat: a[i][k] = −1, dacă nodul i este extremitatea inițială a arcului k
a[i][k] = 1, dacă nodul i este extremitatea finală a arcului k
a[i][k] = 0, altfel
Matricea de incidență a grafului G1, cu muchiile în ordinea
[1,2], [1,3], [2,3], [3,4], [3,5], [4,5], [5,6]:
[1,2] | [1,3] | [2,3] | [3,4] | [3,5] | [4,5] | [5,6] | |
|---|---|---|---|---|---|---|---|
| 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
| 3 | 0 | 1 | 1 | 1 | 1 | 0 | 0 |
| 4 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
| 5 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
| 6 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Proprietățile matricei de incidență:
- la graful neorientat, fiecare coloană are exact două elemente egale cu 1, iar
suma elementelor de pe linia
ieste gradul noduluii; - la graful orientat, fiecare coloană are un element egal cu −1 și un element
egal cu 1, deci suma tuturor elementelor este 0; pe linia
i, numărul valorilor −1 ested⁺(i), iar numărul valorilor 1 ested⁻(i).
Lista muchiilor
Lista muchiilor (la graful orientat, lista arcelor) conține cele m
perechi de noduri care formează muchiile. Ea se memorează într-o matrice cu m
linii și 2 coloane sau într-un vector de înregistrări cu două câmpuri.
k | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| prima extremitate | 1 | 1 | 2 | 3 | 3 | 4 | 5 |
| a doua extremitate | 2 | 3 | 3 | 4 | 5 | 5 | 6 |
Reprezentarea ocupă 2m valori și se folosește atunci când muchiile se
prelucrează una după alta, de exemplu în ordinea costurilor. La fiecare muchie se
pot adăuga și alte informații, cum ar fi lungimea sau costul. Gradul unui nod
este numărul aparițiilor etichetei lui în listă.
Listele de adiacență
Lista de adiacență a nodului i conține toți vecinii lui i la graful
neorientat, respectiv toți succesorii lui i la graful orientat. Graful se
reprezintă prin cele n liste.
Graful neorientat G1
| Nodul | Vecinii |
|---|---|
| 1 | 2, 3 |
| 2 | 1, 3 |
| 3 | 1, 2, 4, 5 |
| 4 | 3, 5 |
| 5 | 3, 4, 6 |
| 6 | 5 |
| 7 | — |
Graful orientat G2
| Nodul | Succesorii |
|---|---|
| 1 | 2, 4 |
| 2 | 3 |
| 3 | 1, 4 |
| 4 | 5 |
| 5 | 3, 6 |
| 6 | 5 |
Numărul total de elemente din liste este 2m la graful neorientat și m la
graful orientat. La graful neorientat, lungimea listei nodului i este gradul
lui; la graful orientat, este gradul extern.
Listele se pot implementa static, cu tablouri, sau dinamic, cu liste simplu înlănțuite: pentru fiecare nod se memorează adresa primului element al listei vecinilor lui.
Compararea reprezentărilor
| Reprezentarea | Memoria ocupată | Există muchia [i, j]? | Vecinii nodului i |
|---|---|---|---|
| matricea de adiacență | n² | o accesare: a[i][j] | parcurgerea liniei i: n pași |
| matricea de incidență | n · m | parcurgerea liniei i: m pași | parcurgerea liniei i și a coloanelor: până la n · m pași |
| lista muchiilor | 2m | parcurgerea listei: m pași | parcurgerea listei: m pași |
| listele de adiacență | n + 2m (neorientat), n + m (orientat) | parcurgerea listei lui i: d(i) pași | parcurgerea listei lui i: d(i) pași |
Matricea de adiacență este potrivită pentru grafurile cu multe muchii și pentru problemele în care se verifică des existența unei muchii. Listele de adiacență sunt potrivite pentru grafurile cu multe noduri și puține muchii și pentru algoritmii care parcurg vecinii fiecărui nod, cum sunt parcurgerea în lățime și cea în adâncime.
Gradele nodurilor unui graf neorientat
Programul citește numărul de noduri, numărul de muchii și muchiile, construiește matricea de adiacență și afișează gradul fiecărui nod, suma gradelor, nodurile izolate și nodurile terminale.
Date de intrare. Pe prima linie n și m; pe fiecare dintre următoarele
m linii, extremitățile unei muchii. Pentru graful G1:
7 7
1 2
1 3
2 3
3 4
3 5
4 5
5 6
#include <iostream>
using namespace std;
const int MAX = 101;
int a[MAX][MAX], n, m;
/* Citeste muchiile si construieste matricea de adiacenta. */
void citire() {
int x, y;
cin >> n >> m;
for (int k = 1; k <= m; k++) {
cin >> x >> y;
a[x][y] = 1; // muchia [x, y]
a[y][x] = 1; // este si muchia [y, x]
}
}
/* Gradul nodului i: numarul valorilor 1 de pe linia i. */
int grad(int i) {
int g = 0;
for (int j = 1; j <= n; j++)
g = g + a[i][j];
return g;
}
/* Suma gradelor tuturor nodurilor. */
int sumaGradelor() {
int s = 0;
for (int i = 1; i <= n; i++)
s = s + grad(i);
return s;
}
/* Afiseaza nodurile care au gradul g. */
void afiseazaNoduri(int g) {
for (int i = 1; i <= n; i++)
if (grad(i) == g)
cout << " " << i;
}
int main() {
citire();
for (int i = 1; i <= n; i++)
cout << "d(" << i << ") = " << grad(i) << "\n";
cout << "Suma gradelor: " << sumaGradelor() << " = 2 * " << m << "\n";
cout << "Noduri izolate:";
afiseazaNoduri(0);
cout << "\nNoduri terminale:";
afiseazaNoduri(1);
return 0;
}
Pentru graful G1 programul afișează gradele din tabelul de mai sus, suma
14 = 2 * 7, nodul izolat 7 și nodul terminal 6. Construirea matricei cere m
pași, iar calculul tuturor gradelor n² pași.
Gradele și vecinii într-un graf orientat
La graful orientat se memorează numai a[x][y] = 1 pentru arcul (x, y).
Gradul extern se obține din linie, iar gradul intern din coloană.
#include <iostream>
using namespace std;
const int MAX = 101;
int a[MAX][MAX], n, m;
void citire() {
int x, y;
cin >> n >> m;
for (int k = 1; k <= m; k++) {
cin >> x >> y;
a[x][y] = 1; // numai arcul (x, y)
}
}
/* Gradul extern al nodului i: arcele care ies din i (linia i). */
int gradExtern(int i) {
int g = 0;
for (int j = 1; j <= n; j++)
g = g + a[i][j];
return g;
}
/* Gradul intern al nodului i: arcele care intra in i (coloana i). */
int gradIntern(int i) {
int g = 0;
for (int j = 1; j <= n; j++)
g = g + a[j][i];
return g;
}
/* Succesorii lui i: nodurile j pentru care exista arcul (i, j). */
void afiseazaSuccesori(int i) {
for (int j = 1; j <= n; j++)
if (a[i][j] == 1)
cout << " " << j;
}
/* Predecesorii lui i: nodurile j pentru care exista arcul (j, i). */
void afiseazaPredecesori(int i) {
for (int j = 1; j <= n; j++)
if (a[j][i] == 1)
cout << " " << j;
}
int main() {
citire();
for (int i = 1; i <= n; i++) {
cout << "Nodul " << i << ": d+ = " << gradExtern(i)
<< ", d- = " << gradIntern(i);
cout << "; succesori:";
afiseazaSuccesori(i);
cout << "; predecesori:";
afiseazaPredecesori(i);
cout << "\n";
}
return 0;
}
Listele de adiacență implementate dinamic
Fiecare listă este o listă simplu înlănțuită. Elementul L[i] memorează adresa
primului element din lista vecinilor nodului i, iar un vecin nou se adaugă la
începutul listei.
#include <iostream>
using namespace std;
struct nod {
int info; // eticheta vecinului
nod *urm; // adresa urmatorului element
};
nod *L[101]; // L[i] = inceputul listei nodului i
int n, m;
/* Adauga nodul y la inceputul listei care porneste din prim. */
void adauga(nod *&prim, int y) {
nod *p = new nod;
p->info = y;
p->urm = prim;
prim = p;
}
/* Citeste muchiile si construieste listele de adiacenta. */
void citire() {
int x, y;
cin >> n >> m;
for (int i = 1; i <= n; i++)
L[i] = NULL;
for (int k = 1; k <= m; k++) {
cin >> x >> y;
adauga(L[x], y); // y devine vecin al lui x
adauga(L[y], x); // x devine vecin al lui y
}
}
/* Gradul nodului i: numarul elementelor din lista lui. */
int grad(int i) {
int g = 0;
for (nod *p = L[i]; p != NULL; p = p->urm)
g++;
return g;
}
int main() {
citire();
for (int i = 1; i <= n; i++) {
cout << "Vecinii nodului " << i << ":";
for (nod *p = L[i]; p != NULL; p = p->urm)
cout << " " << p->info;
cout << " (grad " << grad(i) << ")\n";
}
return 0;
}
La graful orientat se adaugă numai y în lista lui x. Fiecare vecin nou se
așază la începutul listei, deci vecinii se afișează în ordinea inversă citirii:
pentru nodul 3 al grafului G1 se afișează 5 4 2 1.
Lanțul
Lanțul se definește și în graful orientat: acolo nu se ține seama de sensul arcelor, ci doar de faptul că două noduri consecutive sunt legate printr-un arc.
După noduri și după muchii, lanțurile se clasifică astfel:
Exemple în graful G1:
(1, 3, 5, 6)este lanț elementar, de lungime 3;(2, 3, 4, 5, 3, 1)este lanț simplu, fiindcă muchiile[2,3],[3,4],[4,5],[5,3]și[3,1]sunt distincte, dar neelementar, fiindcă nodul 3 apare de două ori;(1, 2, 3, 1, 2)este lanț compus, fiindcă muchia[1,2]se parcurge de două ori;(1, 4, 5)nu este lanț, fiindcă nodurile 1 și 4 nu sunt adiacente.
(1, 3, 5, 6) — lanț elementar(2, 3, 4, 5, 3, 1) — lanț simplu, neelementar: nodul 3 apare de două ori(1, 2, 3, 1, 2) — lanț compus: muchia [1,2] se parcurge la pașii 1 și 4(1, 4, 5) — nu este lanț: muchia [1,4], punctată, nu existăÎntre tipurile de lanțuri există următoarele legături:
- orice lanț elementar este simplu. Dacă o muchie
[x, y]s-ar parcurge de două ori, nodurilexșiyar apărea de două ori în lanț; - dacă un graf conține un lanț de la
xlay, atunci conține și un lanț elementar de laxlay. Dacă un nodzse repetă, porțiunea de lanț dintre două apariții ale luizse elimină, iar operația se repetă până nu mai rămâne niciun nod repetat.
De exemplu, din lanțul (2, 3, 4, 5, 3, 1) se elimină porțiunea 4, 5, 3
dintre cele două apariții ale nodului 3 și se obține lanțul elementar
(2, 3, 1).
(2, 3, 1)Ciclul
Un graf care nu conține niciun ciclu se numește graf aciclic.
Exemple în graful G1:
(3, 4, 5, 3)este ciclu elementar, de lungime 3;(1, 2, 3, 4, 5, 3, 1)este ciclu neelementar: muchiile sunt distincte, dar nodul 3 apare în interiorul ciclului;(1, 2, 1)nu este ciclu: extremitățile coincid, dar muchia[1,2]se parcurge de două ori.
(3, 4, 5, 3) — ciclu elementar(1, 2, 3, 4, 5, 3, 1) — ciclu neelementar: nodul 3 apare de două ori(1, 2, 1) — nu este ciclu: muchia [1,2] se parcurge de două oriÎntr-un graf neorientat, un ciclu are lungimea cel puțin 3: un lanț închis de
lungime 2, de forma (x, y, x), parcurge de două ori muchia [x, y].
Drumul
Drumul este, așadar, un lanț parcurs în sensul arcelor.
Exemple în graful G2:
(1, 4, 5, 6)este drum elementar, de lungime 3;(2, 3, 4, 5, 3, 1)este drum simplu, fiindcă arcele(2,3),(3,4),(4,5),(5,3)și(3,1)sunt distincte, dar neelementar, fiindcă nodul 3 se repetă;(5, 6, 5, 6)nu este drum simplu, fiindcă arcul(5,6)se parcurge de două ori;(1, 3)nu este drum, fiindcă arcul are sensul(3,1); este însă lanț.
(1, 4, 5, 6) — drum elementar(2, 3, 4, 5, 3, 1) — drum simplu, neelementar: nodul 3 apare de două ori(5, 6, 5, 6) — nu este drum simplu: arcul (5,6) se parcurge la pașii 1 și 3(1, 3) — nu este drum: arcul are sensul (3,1)Ca la lanțuri, orice drum elementar este simplu, iar dacă există un drum de la
x la y, există și un drum elementar de la x la y.
Circuitul
Exemple în graful G2:
(1, 2, 3, 1)este circuit elementar, de lungime 3;(5, 6, 5)este circuit elementar, de lungime 2: arcele(5,6)și(6,5)sunt distincte;(1, 2, 3, 4, 5, 3, 1)este circuit neelementar: arcele sunt distincte, dar nodul 3 se repetă;(5, 6, 5, 6, 5)nu este circuit, fiindcă arcele(5,6)și(6,5)se parcurg de câte două ori.
(1, 2, 3, 1) — circuit elementar, de lungime 3(5, 6, 5) — circuit elementar, de lungime 2(1, 2, 3, 4, 5, 3, 1) — circuit neelementar: nodul 3 apare de două ori(5, 6, 5, 6, 5) — nu este circuit: fiecare arc se parcurge de două oriSpre deosebire de ciclul unui graf neorientat, un circuit poate avea lungimea 2, dacă între două noduri există arce în ambele sensuri.
Lanț, ciclu, drum, circuit
Noțiunile se construiesc una din alta, după două criterii: dacă se ține seama de sensul arcelor și dacă extremitățile coincid.
| Extremități oarecare | Extremități care coincid, muchii (arce) distincte | |
|---|---|---|
| fără sensul arcelor (graf neorientat sau orientat) | lanț | ciclu |
| în sensul arcelor (numai graf orientat) | drum | circuit |
Pentru fiecare dintre ele, varianta elementară cere noduri distincte, iar la ciclu și la circuit excepția este nodul de la capete.
Verificarea unui șir de noduri
Programul citește un graf neorientat și un șir de k noduri (k ≥ 2) și
stabilește ce reprezintă șirul: nu este lanț, lanț elementar, lanț simplu
neelementar, lanț compus, ciclu elementar sau ciclu neelementar.
Verificarea se face în trei pași:
- este lanț — pentru fiecare două noduri consecutive se verifică
a[v[i]][v[i+1]] = 1; - este simplu — fiecare muchie parcursă se marchează în matricea
folosit; dacă se ajunge la o muchie deja marcată, lanțul nu este simplu; - este elementar — se compară nodurile două câte două; la un lanț închis, ultimul nod nu intră în comparație, fiindcă el coincide cu primul.
Date de intrare. Graful, în forma de la programul pentru grade, apoi k și
cele k noduri ale șirului.
#include <iostream>
using namespace std;
const int MAX = 101;
int a[MAX][MAX], folosit[MAX][MAX], v[MAX], n, m, k;
void citire() {
int x, y;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> x >> y;
a[x][y] = a[y][x] = 1;
}
cin >> k;
for (int i = 1; i <= k; i++)
cin >> v[i];
}
/* 1. Oricare doua noduri consecutive trebuie sa fie adiacente. */
int esteLant() {
for (int i = 1; i < k; i++)
if (a[v[i]][v[i + 1]] == 0)
return 0;
return 1;
}
/* 2. Nicio muchie nu se parcurge de doua ori; muchiile parcurse
se marcheaza in matricea folosit. */
int esteSimplu() {
for (int i = 1; i < k; i++) {
if (folosit[v[i]][v[i + 1]] == 1)
return 0;
folosit[v[i]][v[i + 1]] = 1;
folosit[v[i + 1]][v[i]] = 1; // aceeasi muchie, in sens invers
}
return 1;
}
/* 3. Niciun nod nu se repeta; la lantul inchis, ultimul nod nu se
compara, fiindca el coincide cu primul. */
int esteElementar() {
int ultim = k;
if (v[1] == v[k])
ultim = k - 1;
for (int i = 1; i < ultim; i++)
for (int j = i + 1; j <= ultim; j++)
if (v[i] == v[j])
return 0;
return 1;
}
int main() {
citire();
if (!esteLant())
cout << "nu este lant";
else if (v[1] == v[k]) { // lant inchis
if (!esteSimplu())
cout << "lant inchis, dar nu este ciclu";
else if (esteElementar())
cout << "ciclu elementar";
else
cout << "ciclu neelementar";
} else {
if (esteElementar())
cout << "lant elementar";
else if (esteSimplu())
cout << "lant simplu, neelementar";
else
cout << "lant compus";
}
return 0;
}
Pentru graful G1, programul dă următoarele rezultate:
| Șirul citit | Rezultatul |
|---|---|
1 3 5 6 | lanț elementar |
2 3 4 5 3 1 | lanț simplu, neelementar |
1 2 3 1 2 | lanț compus |
3 4 5 3 | ciclu elementar |
1 2 3 4 5 3 1 | ciclu neelementar |
1 2 1 | lanț închis, dar nu este ciclu |
1 4 5 | nu este lanț |
Pentru un graf orientat, același program verifică drumurile și circuitele, cu
două modificări: matricea a se construiește numai cu a[x][y] = 1, iar la
marcarea arcului parcurs se șterge atribuirea pentru sensul invers, fiindcă
(x, y) și (y, x) sunt arce diferite.
Graful parțial
Graful parțial se obține din G prin eliminarea unor muchii sau arce.
Eliminând din graful G1 muchiile [3,4] și [5,6] se obține graful parțial
G1p = (X1, V), cu
V = {[1,2], [1,3], [2,3], [3,5], [4,5]}.
Graful parțial păstrează și nodurile 6 și 7, chiar dacă ele au rămas izolate.
Pentru fiecare dintre cele m muchii se alege dacă rămâne sau nu în graful
parțial, deci un graf cu m muchii are 2^m grafuri parțiale, printre care și
graful însuși (V = U) și graful fără muchii (V = ∅). Graful G1 are
2⁷ = 128 de grafuri parțiale.
În matricea de adiacență, graful parțial se obține punând 0 în locul valorilor 1
care corespund muchiilor eliminate: a[3][4] = a[4][3] = 0 și
a[5][6] = a[6][5] = 0.
Subgraful
Se spune că subgraful este generat de mulțimea de noduri Y. El se obține
din G prin eliminarea unor noduri și a tuturor muchiilor incidente cu acestea.
Subgraful grafului G1 generat de mulțimea Y = {1, 2, 3, 5, 6} este
G1s = (Y, V), cu
V = {[1,2], [1,3], [2,3], [3,5], [5,6]}.
Odată cu nodul 4 s-au eliminat muchiile [3,4] și [4,5], iar nodul 7 nu avea
nicio muchie.
Un subgraf este determinat de mulțimea lui de noduri. Un graf cu n noduri are
2ⁿ − 1 submulțimi nevide de noduri, deci 2ⁿ − 1 subgrafuri. Graful G1 are
2⁷ − 1 = 127 de subgrafuri.
Graful ({1, 2, 3}, {[1,2], [1,3]}) nu este subgraf al lui G1: nodurile 2
și 3 sunt în mulțime, dar muchia [2,3] dintre ele lipsește.
Graful parțial și subgraful
Graful parțial se obține eliminând muchii, iar subgraful se obține eliminând noduri, împreună cu muchiile lor.
| Criteriul | Graful parțial | Subgraful |
|---|---|---|
| nodurile | toate nodurile grafului | o submulțime nevidă Y a nodurilor |
| muchiile | o submulțime oarecare a muchiilor | toate muchiile cu ambele extremități în Y |
| cum se obține | prin eliminarea unor muchii | prin eliminarea unor noduri și a muchiilor incidente cu ele |
| câte există | 2^m | 2ⁿ − 1 |
Graful transpus
Graful transpus are aceleași noduri ca G, iar fiecare arc are sensul inversat.
Graful transpus al grafului G2 are arcele
(2,1), (4,1), (3,2), (1,3), (4,3), (5,4), (3,5), (6,5), (5,6).
Arcele (5,6) și (6,5) se transformă unul în celălalt, deci perechea lor
rămâne neschimbată.
Proprietățile grafului transpus:
- matricea de adiacență a lui
Gᵗeste transpusa matricei de adiacență a luiG:aᵗ[i][j] = a[j][i]; - succesorii unui nod în
Gᵗsunt predecesorii lui înG, deci gradul extern și gradul intern își schimbă rolurile; - există drum de la
xlayînGᵗdacă și numai dacă există drum de laylaxînG.
Ultima proprietate se folosește la determinarea componentelor tare conexe: un nod
y este în aceeași componentă cu x dacă este accesibil din x atât în G,
cât și în Gᵗ.
Terminologia grafurilor la examen
În programa de concurs
Noțiunile sunt trecute anume în programele de examen, și la Definitivat, și la Titularizare, la capitolul Teoria grafurilor:
grafuri orientate și neorientate: definiție, metode de reprezentare, terminologie (grad, adiacență, incidență, lanț, lanț elementar, lanț simplu, drum, drum elementar, drum simplu, ciclu, ciclu elementar, circuit, circuit elementar, graf parțial, subgraf, graf transpus)
Ce s-a dat până acum
Terminologia a fost cerută ca temă la Definitivat 2026. Mult mai des, ea apare ca noțiuni preliminare la prezentarea unui algoritm pe grafuri, la Subiectul I:
| Examen | Unde | Ce s-a cerut |
|---|---|---|
| Definitivat 2026, var. 2 | Subiectul I, cerința 1 (15 puncte) | definiția și câte un exemplu pentru drum, drum elementar, drum simplu, circuit, circuit elementar; o problemă rezolvată cu un drum sau un circuit |
| Titularizare 2024, var. 3 | Subiectul I, cerința 1 | la prezentarea arborilor, noțiunile preliminare graf neorientat, lanț, ciclu |
| Definitivat 2021, var. 3 | Subiectul al II-lea | o secvență din programa școlară cu conținutul Grafuri neorientate — terminologie (graf neorientat, lanț, lanț elementar, subgraf, conexitate), pentru care se cerea un item cu alegere multiplă |
| Definitivat 2019, var. 3 | Subiectul I, cerința 1 | la parcurgerea în adâncime, noțiunile preliminare graf, adiacență, parcurgere |
| Titularizare 2016, var. 1 | Subiectul I, cerința 1 | la parcurgerea în lățime, definițiile preliminare graf neorientat, graf orientat, adiacență |
| Titularizare 2015, model | Subiectul I, cerința 1 | la algoritmul lui Dijkstra, definițiile preliminare graf orientat, adiacență, drum, cost |
| Titularizare 2011, var. 2 | Subiectul I, cerința 1 | la conexitate, definițiile preliminare graf neorientat, adiacență, lanț |
| Titularizare 2010, var. 2 | Subiectul I, cerința 1 | la drumurile de cost minim, definițiile preliminare graf orientat, adiacență, drum, cost |
| Titularizare 2008, var. 5 | Subiectul I, cerința 1 | la parcurgerea grafurilor neorientate, definițiile graf neorientat, adiacență, parcurgere |
| Titularizare 2004, var. 1 | Subiectul I, cerința 2 | la parcurgerea grafurilor neorientate, „cinci definiții preliminare” |
| Titularizare 2003, var. 1 | Subiectul I, itemi de tip grilă | între altele, reprezentarea care face cea mai eficientă parcurgerea în adâncime (listele de adiacență) |
Ce punctează baremul
La Definitivat 2026, cele 15 puncte se împart astfel:
| Ce se cere | Punctajul |
|---|---|
| definițiile celor cinci noțiuni: drum, drum elementar, drum simplu, circuit, circuit elementar | 5 × 1p |
| câte un exemplu pentru fiecare noțiune | 5 × 1p |
| enunțul unei probleme adecvate | 1p |
| descrierea coerentă a unei soluții | 1p |
| implementarea soluției | 3p |
La subiectele în care noțiunile sunt preliminare, fiecare definiție valorează de obicei 1 punct: „definiții preliminare, conform cerinței 3 × 1p = 3p” la Titularizare 2016, „noțiuni preliminarii, conform cerinței 3 × 1p = 3p” la Titularizare 2024. Fiecare definiție se scrie complet, cu toate condițiile, deși precedă algoritmul.
Rezolvarea completă a subiectului de la Definitivat 2026 este în pagina Grafuri orientate.
Greșeli frecvente
- Se definește ciclul ca „lanț cu extremitățile egale”, fără condiția ca
muchiile să fie distincte. Cu această definiție,
(1, 2, 1)ar fi ciclu. - Se definește circuitul fără condiția de drum simplu, deși baremul de la Definitivat 2026 o cere explicit.
- Se confundă lanțul elementar cu lanțul simplu: elementar se referă la noduri, simplu se referă la muchii.
- Se afirmă că orice lanț simplu este elementar. Implicația este inversă: orice lanț elementar este simplu.
- La ciclul elementar se cere ca toate nodurile să fie distincte, uitând excepția primului și a ultimului nod, care coincid.
- Se confundă graful parțial cu subgraful. Graful parțial păstrează toate nodurile; subgraful păstrează toate muchiile dintre nodurile rămase.
- La subgraf se elimină un nod, dar rămâne o muchie incidentă cu el, sau se elimină o muchie dintre două noduri păstrate.
- La graful neorientat se completează numai
a[x][y] = 1, fărăa[y][x] = 1, iar matricea nu mai este simetrică. - La graful orientat se calculează gradul intern pe linie în loc de coloană.
- Se afirmă că suma elementelor matricei de adiacență a unui graf neorientat
este
m. Ea este2m, fiindcă fiecare muchie apare de două ori. - Se folosește matricea de incidență a grafului neorientat pentru un graf orientat, fără valorile −1, iar sensul arcelor se pierde.
Verificare rapidă
Folosește întrebările următoare înainte să consideri rezolvarea terminată:
- Am precizat dacă graful este neorientat sau orientat și am folosit „muchie”, respectiv „arc”?
- Definiția ciclului și a circuitului conține condiția ca muchiile, respectiv arcele, să fie distincte?
- La noțiunile elementare am precizat excepția extremităților care coincid?
- Fiecare definiție are un exemplu verificat pe un graf dat explicit?
- Exemplul pentru „drum simplu” este neelementar, ca să se vadă deosebirea față de drumul elementar?
- La graful parțial și la subgraf am spus ce se elimină: muchii, respectiv noduri împreună cu muchiile lor?
Exerciții de fixare
- Scrie matricea de adiacență, matricea de incidență și listele de adiacență
pentru graful neorientat cu nodurile 1, 2, 3, 4, 5 și muchiile
[1,2],[1,4],[2,3],[2,4],[3,5],[4,5]. - Pentru graful de la exercițiul 1, dă câte un exemplu de lanț elementar de lungime 4, lanț simplu neelementar, ciclu elementar de lungime 3 și ciclu elementar de lungime 5.
- Scrie un program care citește o matrice pătratică și verifică dacă este binară, are zero pe diagonala principală și este simetrică, adică dacă reprezintă un graf neorientat.
- Scrie un program care citește lista arcelor unui graf orientat și afișează lista arcelor grafului transpus și nodurile care au gradul intern egal cu gradul extern.
- Scrie un program care citește matricea de adiacență a unui graf neorientat și
o mulțime de noduri
Y, apoi afișează muchiile subgrafului generat deY. - Modifică programul de verificare a unui șir de noduri astfel încât să lucreze pe un graf orientat și să afișeze: nu este drum, drum elementar, drum simplu neelementar, drum compus, circuit elementar sau circuit neelementar.
- Câte grafuri parțiale și câte subgrafuri are un graf neorientat cu 5 noduri și 6 muchii? Justifică fiecare număr.
Flashcarduri
Citește întrebarea și formulează răspunsul. Apoi întoarce flashcardul și verifică.
O pereche ordonată de mulțimi G = (X, U), în care X este o mulțime finită și nevidă de noduri, iar U este o mulțime de perechi de noduri distincte.
- la graful neorientat, perechile din U sunt neordonate și se numesc muchii;
- la graful orientat, perechile din U sunt ordonate și se numesc arce.
- gradul d(x) este numărul muchiilor care au o extremitate în nodul x;
- nodul terminal are gradul 1;
- nodul izolat are gradul 0.
- gradul extern d⁺(x) este numărul arcelor care ies din x;
- gradul intern d⁻(x) este numărul arcelor care intră în x.
2m, fiindcă fiecare muchie contribuie cu 2 la suma gradelor; de aici, numărul nodurilor de grad impar este par.
Matricea pătratică de ordinul n în care a[i][j] = 1 dacă există muchia [i, j] (arcul (i, j)) și 0 altfel; la graful neorientat este simetrică.
O succesiune de noduri în care oricare două noduri consecutive sunt adiacente; lungimea lui este numărul de muchii parcurse.
- lanțul elementar are nodurile distincte două câte două;
- lanțul simplu are muchiile distincte două câte două;
- orice lanț elementar este simplu, dar nu și invers.
- ciclul este un lanț simplu ale cărui extremități coincid;
- ciclul elementar nu repetă niciun nod, în afară de nodul de la capete.
Extremitățile coincid, dar muchia [1,2] se parcurge de două ori, deci lanțul nu este simplu.
- drumul este o succesiune de noduri în care oricare două noduri consecutive sunt legate printr-un arc de la primul la al doilea;
- drumul elementar are nodurile distincte două câte două;
- drumul simplu are arcele distincte două câte două.
- circuitul este un drum simplu ale cărui extremități coincid;
- circuitul elementar nu repetă niciun nod, în afară de nodul de plecare, care este și nodul de sosire.
- graful parțial păstrează toate nodurile și se obține prin eliminarea unor muchii;
- subgraful se obține prin eliminarea unor noduri și a tuturor muchiilor incidente cu ele;
- un graf cu n noduri și m muchii are 2^m grafuri parțiale și 2ⁿ − 1 subgrafuri.
Graful cu aceleași noduri, în care fiecare arc are sensul inversat; matricea lui de adiacență este transpusa matricei grafului inițial.
Ai parcurs toate flashcardurile.
- Știu: 0
- De repetat: 0
Din tastatură: Spațiu întoarce flashcardul, ← și → trec la flashcardul precedent sau următor.
Hartă mentală
Pentru recapitulare, ascunde ideile, spune ce cuprinde fiecare ramură, apoi apasă pe titlul ei și verifică.
- graful parțial: se elimină muchii
- subgraful: se elimină noduri
- graful transpus: arcele inversate
- drum: lanț în sensul arcelor
- drum elementar, drum simplu
- circuit: drum simplu închis
- circuit elementar
- lanț elementar: noduri distincte
- lanț simplu: muchii distincte
- ciclu: lanț simplu închis
- ciclu elementar
Grafuri. Terminologie
- G = (X, U)
- graful neorientat: perechi neordonate
- graful orientat: perechi ordonate
- muchii, noduri adiacente
- gradul d(x)
- nod terminal, nod izolat
- suma gradelor = 2m
- arce, succesori, predecesori
- gradul extern, gradul intern
- suma gradelor externe = m
- matricea de adiacență
- matricea de incidență
- lista muchiilor
- listele de adiacență
Test grilă
Bifează un răspuns la fiecare întrebare, apoi apasă „Vezi nota”. Răspunsurile corecte se arată după corectare.
Materialul acesta se citește pe educamp.ro și nu se tipărește.
Surse (4)
- „Informatică. Manual pentru clasa a XI-a”, Editura Didactică și Pedagogică, București
- Programa pentru examenul de definitivare în învățământ, disciplina Informatică, cap. 5 „Teoria grafurilor”
- Programa pentru concursul de ocupare a posturilor didactice, disciplina Informatică, cap. 5 „Teoria grafurilor”
- Subiecte și bareme publicate, Definitivat și Titularizare, informatică, 2002–2026