Cod sursa(job #1606388)

Utilizator iulian_f2kGuraliuc Iulian iulian_f2k Data 20 februarie 2016 10:55:32
Problema Arbore partial de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include <iostream> // se aplica pe GRAF CONEX si NEORIENTAT
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>        //priorityQueue
using namespace std;
struct Muchie
{
    int x, y, c;
    friend bool operator>(const Muchie &a, const Muchie &b);
};
bool operator>(const Muchie &a,const Muchie &b)
{
    return a.c > b.c;
}
priority_queue<Muchie, vector<Muchie>, greater<Muchie> > H;   //min-heap

vector<int> h, T;       //se folosesc pentru simularea arborelui
int N, M;

void citire();
int comp(Muchie i, Muchie j);
int Find(int x);
void Union(int x, int y);
void Kruskal();

int main()
{
    citire();
    Kruskal();
    return 0;
}
void citire()
{
    freopen("apm.in","rt",stdin);
    freopen("apm.out","wt",stdout);
    Muchie aux;
    cin>>N>>M;
    for(int i=0; i<M; ++i){
        scanf("%d %d %d", &aux.x, &aux.y, &aux.c);
        H.push(aux);
    }
}
int Find(int x)
{
    int rx = x, y;
    while(rx != T[rx])    rx = T[rx];
    while(x != rx)  //Regula de compresie a drumului de la x la radacina sa
    {
        y = T[x];
        T[x] = rx;
        x = y;
    }
    return rx;
}
void Union(int x, int y)
{
    if(h[x] > h[y])
        T[y] = x;
    else if(h[x] < h[y])
        T[x] = y;
    else{
        h[x]++;
        T[x] = y;
    }
}
void Kruskal()
{
    int cTotal=0, nrM=0, rx, ry, x, y;             //numarul muchiilor selectate e 0
    vector<pair<int, int> >S;                        //vectorul in care retinem muchiile arborelui solutie
    for(int i=0; i<=N; ++i)                          //initial fiecare nod face parte dintr-un arbore separat
        T.push_back(i);
    h.assign(N+1, 1);                                //initial toate nodurile sunt pe primul nivel
    while(nrM < N-1 && !H.empty())
    {
        x = H.top().x;
        y = H.top().y;
        rx = Find(x);
        ry = Find(y);
        if( rx != ry)                                //daca nu se formeaza ciclu
        {
            Union(x, y);                             //unificarea arborilor
            nrM++;                                   //creste numarul de muchii selectate
            S.push_back(make_pair(x, y));
            cTotal += H.top().c;
        }
        H.pop();
    }
    /*if(H.empty() && nrM < N-1){                      //Daca am parcurs toate muchiile si inca nu am construit tot arborele
        cout<<"Nu exista solutie\n";
        return;
    }*/
    //afisare
    cout<<cTotal<<'\n';
    cout<<nrM<<'\n';
    for(int i=0; i<N-1; ++i)
        cout<<S[i].first<<' '<<S[i].second<<'\n';
}