Sunteți pe pagina 1din 3

Algoritmul lui Kruskal este un algoritm de tip greedy care gsete arborele parial

de cost minim pentru un graf conex ponderat.


Termeni utilizai:
- Graf conex = graf ntre care oricare dou vrfuri ale acestuia exist cel puin un
drum.
- Graf ponderat = graf n care fiecrei muchii i este asociat o valoare numit cost.
Dac graful nu este conex, atunci algoritmul va gsi o pdure parial de cost minim.
- Pdure = graf n care componentele conexe sunt arbori.
Pasul 1: ordoneaz cresctor lista muchiilor n funcie de costuri
Pasul 2: creeaz un arbore, verificnd la fiecare pas dac muchia adugat nu nchide
un ciclu (verific dac capetele muchiei nu aparin aceleiai componente conexe)
Pasul 3: construiete arborele parial de cost minim

La sfritul algoritmului, pdurea are doar o component care reprezint
un arbore parial de cost minim al grafului.
Pentru a rspunde rapid la ntrebrile de tipul sunt n acelai arbore nodurile x i y?
avem nevoie de o structur de date numit Pduri de mulimi disjuncte.

Aceasta reine o partiionare a mulimii ,1,.,n- n mai multe mulimi disjuncte,
permite unirea a dou mulimi i rspunde la ntrebri de forma care este mulimea din
care face parte x.

Structura se ntreine ca o pdure de arbori n care fiecare arbore reprezint o
mulime, aadar, printr-un vector de tai.

Unirea a dou mulimi se realizeaz prin unirea celor dou rdcini ale arborilor.
Exemplu:
pentru cele dou rdcini x i y, T[tata(y)] = tata(x) )

Determinarea mulimii din care face parte x se face parcurgnd lanul de la nodul x la
tata.

Aceast implementare are o complexitate de N pai per ntrebare. Pentru a reduce
complexitatea, la fiecare iteraie a funciei tata, schimbm T*x+ cu valoarea returnat de
aceast funcie.


Alte funcii utile folosite:
- sortarea predefinit: sort(primul_elem,ultimul_elem,criteriu_de_sortare)




struct Muchie{int x, y, c;};
int T[50], n, m, nr;
Muchie edge[50], sol[50];

bool comp(Muchie a, Muchie b) //criteriul de comparare
{
return a.c<b.c;
}
int tata(int x) //determinarea mulimii din care face parte x
{
if (x == T[x])
return x;
return tata(T[x]);
}
void merge(int x, int y) //funcia de unire a dou mulimi prin unirea rdcinilor lor (x i y)
{
x=tata(x); y=tata(y);
if (x != y)
T[y] = x;
}
void kruskal()
{
sort(edge+1, edge+m+1,comp); // sortarea cresctoare n funcie de costuri
int C = 0; // variabila ce va reine costul total al pdurii finale obinute
for(int i=1;i<=n;i++) // iniializarea vectorului de tai cu i; iniial considerm fiecare nod
T[i]=i; // aparinnd mulimii format doar din el nsui
for (int i=1;i<=m;i++)
if(tata(edge[i].x)!=tata(edge[i].y))
{
merge(edge[i].x,edge[i].y); // unirea celor dou mulimi dac rdcinile lor nu se gsesc n
sol[++nr]=edge[i]; // aceeai component conex i construcia vectorului soluie
C+=edge[i].c;
}
out<<C<<"\n"<<nr<<"\n";
for (int i=1;i<=nr;i++)
out<<sol[i].x<<" "<<sol[i].y<<"\n";
}
int main(){
in>>n>>m;
for (int i=1;i<=m;i++)
in>>edge[i].x>>edge[i].y>>edge[i].c;
kruskal();
return 0;
}