Cod sursa(job #2257468)

Utilizator slym777Darii Dan slym777 Data 10 octombrie 2018 09:20:23
Problema Arbore partial de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.95 kb
#pragma GCC optimize("O3")

#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>

using namespace std;

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

struct muchie /// practic este structura in care memorez muchiile
{
    int x,y,c;  /// x- primul nod, y al doilea nod, c- cost
    bool apm;
};

int tata[200000], h[200000]; /// vector de tata pentru memorarea arborelui de reprezentati, h pentru inaltimea arborelor
vector < muchie > E; /// vectorul de muchii dat din fisier

bool cmp( muchie A, muchie B)
{
    return A.c < B.c;
}

int reprezentant(int x)   /// calculez reprezentatul
{
    if (tata[x]==x) /// reprezentatul va fi varful arborelui, astfel daca tata[x] = x inseamna ca x e vf arborelui si am gasit reprezentatul
        return x;
   tata[x] = reprezentant((tata[x]));
   return tata[x];
}

void reuneste(int x, int y)  /// reunesc arborele de reprezentanit==ti
{
    int r1 = reprezentant(x);   /// r1 - varful arborelui din care face parte x
    int r2 = reprezentant(y);  /// r2 - varful arborelui din care face parte y
    if ( h[r1] == h[r2])
        {
        tata[r1] = r2; /// daca sunt egale nu conteaza pe care de care il leg
        h[r2]++;   /// si inaltimea creste cu 1
        }
    else if (h[r1] < h[r2])       /// daca inaltimea arborelui(x) < cea a aarborelui(y), atunci unesc arborele mai mic la cel mai mare, pentru a obtine o lungime minima a arborelui nou format
        tata[r1] = r2;  /// deci unesc arborele(x) de reprezentatul(radacina arb.) lui y
    else  /// la fel si aici
        tata[r2] = r1;
}

int main()
{
    ios_base::sync_with_stdio(0);
    fin.tie(0); fout.tie(0);

    int n,m,suma = 0,nr = 0;
    fin >> n >> m;
    E.resize(m); /// dam resize si automat toate valorile E[i] devin 0, e mai usor pentru ca nu dam de fiecare data pushback, pentur a mari vectorul
    for ( int i = 0 ; i < m; i++)
        fin >>  E[i].x >> E[i].y >> E[i].c; /// introducem primul si al 2 nod al muchii, costul
    sort (E.begin(), E.end(), cmp);      /// sortam muchiile pentru a obtine arbore de cost minim
    for ( int i = 0 ; i < n; i++)
        {
            tata[i] = i;            /// initializam practic fiecare nod ca o componente conexa
            h[i] = 1;
        }
    for ( int i = 0; ((i < m) && (nr < n-1)); i++)
    {
        if (reprezentant(E[i].x) != reprezentant(E[i].y))  /// daca reprezentatii nodurilor sunt diferiti, adica din 2 componente conexe diferite
        {
            reuneste(E[i].x, E[i].y);              /// reunesc arborele de reprezentanti
            E[i].apm = true;                        /// aleg muchia data in apcm meu
            nr++;
            suma = suma + E[i].c;
        }
    }
    fout << suma << endl << nr << endl;
    for ( auto a:E)   /// o alta metoda de citire a datelor din vector
        if (a.apm == true)
            fout << a.x << " " << a.y << endl;
    fin.close();
    fout.close();
    return 0;
}