Cod sursa(job #2403158)

Utilizator Marius92roMarius Marius92ro Data 11 aprilie 2019 12:15:45
Problema Arbore partial de cost minim Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.69 kb
#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;

}