Cod sursa(job #2413177)

Utilizator Marius92roMarius Marius92ro Data 22 aprilie 2019 23:32:15
Problema Arbore partial de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.63 kb
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <vector>
#include <algorithm>

using namespace std;

#define INFINIT 1000000

                    /*   O(N^2) la cautarea unui nod nevizitat )  */

struct PAIR{

    int vecin, cost;

};

ifstream fin("apm.in");
ofstream fout("apm.out");

int nrNoduri, nrMuchii, nodStart, costArborePartial, nrMuchiiArborePartial, *vectorTati, *vectorDistante;
bool *vizitatNoduri;
vector <PAIR> *listeAdiacenta;

void prim(){

    for ( int i = 1; i <= nrNoduri; i++){ //initializarea vectorilor
        vectorDistante[i] = INFINIT;
        vectorTati[i] = 0;
        vizitatNoduri[i] = false;
    }

    nodStart = 1;
    vectorDistante[nodStart] = 0;

    int nrComponenteConexe = 1, nodCurent = 0;

    while ( nrComponenteConexe <= nrNoduri ){ //cat timp mai sunt noduri de prelucrat

              int distantaMinima = INFINIT;

              for ( int i = 1; i <= nrNoduri; i++){ //extrag nodul cu distanta minima ( dintre nodurile neprelucrate )
                        if ( !vizitatNoduri[i] ){ //daca nodul nu a fost prelucrat
                                if ( distantaMinima > vectorDistante[i] ){
                                    distantaMinima = vectorDistante[i];
                                    nodCurent = i;
                                }
                        }
              }

              costArborePartial += distantaMinima;

              if ( nodCurent != nodStart ) //muchia de la nodulStart la nodulStart nu se ia in calcul
                            nrMuchiiArborePartial++;

              vizitatNoduri[nodCurent] = true; //marchez nodul gasit ca fiind prelucrat

              int lim = listeAdiacenta[nodCurent].size();

              for ( int i = 0; i < lim; i++ ){ //actualizez distantele vecinilor neadaugati in APM

                    int vecin = listeAdiacenta[nodCurent][i].vecin;
                    int costVecin = listeAdiacenta[nodCurent][i].cost;

                    if ( !vizitatNoduri[vecin] && costVecin < vectorDistante[vecin] ){ //daca vecinul nu este deja adaugat in APM
                                                                                      // si distanta trebuie actualizata
                                vectorDistante[vecin] = costVecin;
                                vectorTati[vecin] = nodCurent;
                    }
              }

              nrComponenteConexe++;
    }

}

int main(){

    if ( !fin ){
        cout << "\nEroare la deschiderea fisierului !\n";
        exit(-1);
    }

    fin >> nrNoduri;

    vectorTati = NULL;
    vectorDistante = NULL;
    vizitatNoduri = NULL;
    listeAdiacenta = NULL;

    vectorTati = new int[nrNoduri + 5];
    vectorDistante = new int[nrNoduri + 5];
    vizitatNoduri = new bool[nrNoduri + 5];
    listeAdiacenta = new vector <PAIR> [nrNoduri + 5];

    if (!vectorTati || !vectorDistante || !vizitatNoduri || !listeAdiacenta){
        cout << "\nEroare la alocarea dinamica !\n";
        exit(-1);
    }

    fin >> nrMuchii;

    for (int i = 1; i <= nrMuchii; i++){

            PAIR P;
            int x, y, cost;

            fin >> x >> y >> cost;

            P.vecin = y, P.cost = cost;
            listeAdiacenta[x].push_back(P);   //graf neorientat

            P.vecin = x;
            listeAdiacenta[y].push_back(P);

    }

    prim();

    fout << costArborePartial << "\n" << nrMuchiiArborePartial << "\n";

     for ( int i = 1; i <= nrNoduri; i++)
                if ( i != nodStart )
                        fout << i << " " << vectorTati[i] << "\n";

    return 0;

}