Arbori-Determinare arbore partial de cost minim

Enunt

Se dă un graf neorientat G=(U,X), conex, ponderat cu N noduri. Se cere sa se arborele partial de cost minim asociat grafului dat.

Datele de intrare se vor citi din fisierul text graf.in, care conţine pe prima linie două numere naturale n (numărul de noduri) şi m (numărul de muchii), iar pe următoarele m linii triplete de numere naturale x, y, cost, care reprezintă muchia (x,y) şi costul asociat acesteia.

Datele de iesire vor fi afişate pe ecran în următorul format:

  • muchiile care formează arborele parţial de cost minim

  • costul arborelui partial determinat rezultatul va fi afisat pe ecran.

graf.in

9 11

3 8 1

2 3 2

1 2 1

1 3 2

1 4 1

4 5 2

5 6 3

3 6 1

3 9 2

8 9 3

7 8 3

Rezultat

Arborele parţial de cost minim conţine muchiile:

(3,8), (1,2), (1,4), (3,6), (6,9), (2,3), (4,5), (7,8)

Costul APCM:12

Indicaţii de rezolvare:

Există situaţii în care se poate asocia o valoare suplimentară unei muchii, valoare care reprezintă distanţa dintre noduri, costul asociat muchiei, timpul de parcurs al muchiei, etc. Această nouă caracteristică se mai numeşte si pondere.

Pentru a memora un graf ponderat în memoria calculatorului se pot utiliza mai multe variante :

  • matricea de adiacenţă: care in dreptul muchiei (x,y) va memora valoarea costului muchiei

    • matricea costurilor: este o matrice care are un număr de linii egal cu numărul de muchii şi trei coloane care memorează muchia (x,y) şi costul acesteia.

Definiţie: Costul grafului este suma ponderilor tuturor muchiilor din graf.

Definiţie: A

Program Code Bloks:

//Algoritmul lui KRUSKAL

#include<iostream>

#include<fstream>

using namespace std;

int a[50][4],n,m; //n-nr. de noduri, m-nr. de muchii

//citirea din fisier a informatiilo si construirea matricei costurilor

void citire(int a[50][4], int &n, int &m)

{ ifstream f("matrice.in");

f>>n>>m;

for(int i=1;i<=m;i++)

f>>a[i][1]>>a[i][2]>>a[i][3];

f.close();

}

//afisarea pe ecran

void afisare(int a[50][4], int m)

{cout<<"Maticea costurilor este:"<<endl;

for(int i=1;i<=m;i++)

{ for(int j=1;j<=3;j++)

cout<<a[i][j]<<" ";

cout<<endl;

}

}

//ordonarea matricei costurilor dupa ultima coloana

void ordoneaza(int a[50][4], int m)

{//Buble – sort

int ok;//presupun matricea ordonata dupa ultima coloana

do

{ok=1;

for(int i=1;i<=m-1;i++)

if(a[i][3]>a[i+1][3])

{ //se inverseaza linia i cu linia i+1

for(int j=1;j<=3;j++)

{int aux=a[i][j];

a[i][j]=a[i+1][j];

a[i+1][j]=aux;

ok=0;

}

}while(ok==0);

}

void kruskal(int a[50][4],int m,int n)

{ //construim un vector v cu un numar de elemente egal cu numarul de noduri,

// v[i]->componenta conexa a nodului i

int v[20],cost=0,nr_muchii=0,k;

for(int i=1;i<=n;i++)

v[i]=i; //fiecare nod formeaza o componenta conexa

k=1;//numarul liniei care se prelucreaza dim matrice

cout<<"APCM contine urmatoarele muchii:"<<endl;

while(nr_muchii<n-1)

{

//linia k se adauga sau nu la APCM?

int x=a[k][1];

int y=a[k][2];

if(v[x]!=v[y])//x si y fac parte din componente conexe diferite

{

cost=cost+a[k][3];

nr_muchii++;

cout<<"("<<x<<","<<y<<")";

int aux=v[y];

for(int i=1;i<=n;i++)

if (v[i]==aux)

v[i]=v[x];

}

k++;

}

cout<<"Costul APCM este "<<cost<<endl;

}

int main()

{ citire(a,n,m);

cout<<"Initial:"<<endl;

afisare(a,m);

ordoneaza(a,m);

cout<<"Dupa ordonare crescatoare a coloanei 3:"<<endl;

afisare(a,m);

kruskal(a, m, n);

return 0;

}