De ce contează?
Primăria închide câteva străzi pentru reparații. Orașul rămâne întreg — niciun cartier nu dispare de pe hartă — dar unele drumuri nu mai pot fi folosite. Harta cu străzile rămase e un graf parțial al orașului: exact aceleași noduri, doar o parte din legături.
Ce este
Un graf are două ingrediente: nodurile (cine) și muchiile (cine cu cine). Când construiești un graf parțial, atingi un singur ingredient: muchiile.
Formal: fie un graf neorientat G = (V, E), unde V e mulțimea nodurilor și E
mulțimea muchiilor. Un graf parțial al lui G este un graf G' = (V, E')
în care:
- mulțimea nodurilor este exact aceeași — toate nodurile din
Vse păstrează; - mulțimea muchiilor
E'este o submulțime a luiE.
Cu alte cuvinte, un graf parțial se obține din G ștergând muchii (eventual
niciuna, eventual toate), dar fără să atingi nodurile. Cazurile extreme sunt
și ele grafuri parțiale: G însuși (nu ștergi nimic) și graful cu toate nodurile
dar zero muchii (ștergi tot).
Testul rapid, cerut mereu la concurs: numără nodurile. La un graf parțial
numărul de noduri rămâne n, neschimbat — se schimbă doar muchiile. Dacă a
dispărut măcar un nod, ai un subgraf, nu un graf parțial. Parțial atinge
muchiile; subgraful atinge nodurile.
De aici iese și numărarea: un graf cu m muchii are exact grafuri parțiale,
fiindcă pentru fiecare muchie decizi independent dacă o păstrezi sau o ștergi
— două variante per muchie, deci de ori.
Pentru pătratul de mai jos, cu muchii, există grafuri parțiale.
De ce merită reținută noțiunea: cel mai celebru graf parțial este arborele
parțial — un graf parțial care e conex și fără cicluri, adică păstrezi exact
atâtea muchii cât să legi toate cele n noduri. Pe el se construiește arborele
parțial de cost minim (Kruskal, Prim), unul dintre algoritmii-vedetă ai clasei
a XI-a. Definiția de azi e fundația lui.
Cum arată
Pornește vizualizarea de la graful complet și urmărește ce se întâmplă când păstrezi doar unele muchii: nodurile stau pe loc, iar legăturile se răresc.
Folosește ← și → ca să pășești muchie cu muchie, sau Redă pentru animație. Ce trebuie să vezi: niciun nod nu părăsește desenul — doar muchiile apar sau dispar. Exact asta e definiția grafului parțial în mișcare.
Același lucru, pe un exemplu concret cu liste de muchii. Pornim de la un graf pe 4 noduri, în formă de pătrat:
1-2 | 2-3 | 3-4 | 4-1 |
0 | 1 | 2 | 3 |
Construim un graf parțial ștergând muchia 2-3. Nodurile rămân toate patru, dar lista de muchii pierde un element:
1-2 | - | 3-4 | 4-1 |
0 | 1 | 2 | 3 |
stearsa |
Observă că nodul 2 și nodul 3 există în continuare în G' — doar legătura
directă dintre ele a dispărut. Asta îl deosebește de un subgraf, unde am fi putut
elimina chiar nodul 2 cu totul (și, odată cu el, muchiile 1-2 și 2-3).
Implementare C++
Citim graful întreg și indicii muchiilor pe care le păstrăm. Construim graful
parțial copiind doar aceste muchii în matricea de adiacență. Toate cele n
noduri rămân prezente — matricea are aceeași dimensiune, doar pornește goală.
#include <iostream>
using namespace std;
int adiacenta[105][105]; // graful partial: 1 daca exista muchie
int x[10005], y[10005]; // capetele celor m muchii din G
int main() {
int n, m;
cin >> n >> m; // n noduri, m muchii in graful G
for (int i = 0; i < m; i++) {
cin >> x[i] >> y[i]; // muchia i leaga nodurile x[i] si y[i]
}
int k;
cin >> k; // cate muchii pastram in graful partial
for (int t = 0; t < k; t++) {
int idx;
cin >> idx; // indicele muchiei pastrate (0..m-1)
// pastram doar aceasta muchie; nodurile raman toate
adiacenta[x[idx]][y[idx]] = 1;
adiacenta[y[idx]][x[idx]] = 1;
}
// afisam graful partial: toate cele n noduri raman prezente
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << adiacenta[i][j] << " ";
}
cout << "\n";
}
// numarul de grafuri partiale: 2^m (long long, altfel overflow)
if (m <= 62) {
cout << "grafuri partiale: " << (1LL << m) << "\n"; // ex: m=4 -> 16
}
return 0;
}
// Pentru n=4, muchiile 1-2,2-3,3-4,4-1 si k=3 muchii pastrate (0,2,3),
// graful partial are muchiile 1-2, 3-4, 4-1 (muchia 2-3 lipseste).Cheia: bucla de afișare merge de la 1 la n indiferent câte muchii am
păstrat. Nodurile nu se ating niciodată — doar matricea de muchii pornește goală
și primește exact muchiile selectate.
Confuzia cu subgraful. Când ți se cere un graf parțial și tu elimini și
noduri, ai construit un subgraf — la concurs răspunsul e greșit chiar dacă
desenul „arată bine”. Regula scurtă: la parțial, n rămâne neschimbat.
Overflow la numărare. Numărul de grafuri parțiale e , iar 1 << m pe
int dă rezultat greșit deja de la . Folosește 1LL << m (sau
long long) — un graf complet cu doar 9 noduri are deja muchii.