Pagini recente » Cod sursa (job #863763) | Cod sursa (job #1032542) | Cod sursa (job #2188732) | Cod sursa (job #255238) | Cod sursa (job #2403158)
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct PAIR{
int muchieX, muchieY, costMuchie;
}PAIR;
PAIR P;
ifstream fin("apm.in");
ofstream fout("apm.out");
int nrNoduri, nrMuchii, costArborePartial, nrMuchiiArborePartial, *vectorTati, *rang;
vector <PAIR> muchii;
bool *vizitatMuchii;
int Radacina(int nod){
int k = nod;
while ( vectorTati[k] != 0 ) //caut radacina nodului
k = vectorTati[k];
while ( vectorTati[nod] != 0 ){ //actualizez vectorul de tati cu radacina gasita
vectorTati[nod] = k;
nod = vectorTati[nod];
}
return nod;
}
void Unire(int radacinaX, int radacinaY){ //leg radacinile a doua componente conexe
if ( radacinaX != radacinaY ){ //in caz ca radacinile sunt diferite -> avem doua submultimi ( componente conexe ) diferite
if(rang[radacinaX] > rang[radacinaY]) //unesc multimea cu rang mai mic de cea cu rang mai mare
vectorTati[radacinaY] = radacinaX;
else
vectorTati[radacinaX] = radacinaY;
if( rang[radacinaX] == rang[radacinaY] ) //in caz ca rangurile erau egale atunci cresc rangul noii multimi cu 1
rang[radacinaY] ++;
}
}
int cmp(PAIR X, PAIR Y){
return X.costMuchie < Y.costMuchie;
}
void kruskal(){ //initial toate nodurile sunt izolate, deci apm - ul este creat pe parcurs prin reunirea subarborilor
int nrComponenteConexe = nrNoduri; //nrComponenteConexe reprezinta nr nodurilor grafului
for ( int i = 1; i <= nrNoduri; i++){ // ( se pleaca de la ideea de arbore izolat , deci toate nodurile vor fi izolate )
vectorTati[i] = 0;
rang[i] = 0;
}
costArborePartial = 0 , nrMuchiiArborePartial = 0;
int lim = muchii.size();
for(int i = 0; i < lim && nrComponenteConexe > 1 ; i++){ //mergem pe fiecare muchie ( cat timp mai avem muchii si nu am parcurs toate nodurile )
//cout << "test1";
int radacinaX = Radacina(muchii[i].muchieX);
int radacinaY = Radacina(muchii[i].muchieY);
//cout << "test2";
if ( radacinaX != radacinaY ){ //daca radacinile difera inseamna ca avem componente conexe diferite
vizitatMuchii[i] = true;
costArborePartial += muchii[i].costMuchie;
nrMuchiiArborePartial++;
Unire(radacinaX,radacinaY);
nrComponenteConexe--; //scadem nr componentelor conexe ( efectiv am unit 2 noduri, deci vom scadea nr de componente conexe )
}
}
}
int main(){
if ( !fin ){
cout << "\nEroare la deschiderea fisierului !\n";
exit(-1);
}
fin >> nrNoduri;
vectorTati = NULL;
vectorTati = new int[nrNoduri + 5];
rang = new int[nrNoduri + 5];
if (!vectorTati || !rang){
cout << "\nEroare la alocarea dinamica !\n";
exit(-1);
}
fin >> nrMuchii;
vizitatMuchii = new bool[nrMuchii + 5];
if (!vizitatMuchii){
cout << "\nEroare la alocarea dinamica !\n";
exit(-1);
}
for (int i = 0; i < nrMuchii; i++) {
fin >> P.muchieX >> P.muchieY >> P.costMuchie;
muchii.push_back(P);
vizitatMuchii[i] = false;
}
sort(muchii.begin(),muchii.end(),cmp); //sortez muchiile in ordine descrescatoare dupa cost
kruskal();
fout << costArborePartial << "\n" << nrMuchiiArborePartial << "\n";
for ( int i = 0; i < nrMuchii; i++)
if ( vizitatMuchii[i] )
fout << muchii[i].muchieX << " " << muchii[i].muchieY << endl;
return 0;
}