Cod sursa(job #2707917)

Utilizator Mihai_EduardMihai Eduard Mihai_Eduard Data 17 februarie 2021 22:43:04
Problema Arbore partial de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include <iostream>
#include <fstream>
#include <vector>

#define MX 200001
#define inf 2000000000

using namespace std;

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

int n, m, total;
vector < pair<int,int> > v[MX];
int key[MX], P[MX], H[MX], poz[MX], L;
bool fr[MX];

void citire()
{
    fin>>n>>m;
    int x, y, cost;
    for(int i=1;i<=m;i++)
    {
        fin>>x>>y>>cost;
        v[x].push_back({y,cost});
        v[y].push_back({x,cost});
    }
}

void actualizare(int p)
{
    while(p>1 and key[H[p]]<key[H[p/2]])
    {
        swap(H[p],H[p/2]);
        swap(poz[H[p]],poz[H[p/2]]);
        p/=2;
    }
}

void push_MinHeap(int nod)
{
    H[++L]=nod;
    poz[nod]=L;
    actualizare(L);
}

int radacina_MinHeap()
{
    int rad=H[1];
    swap(H[1],H[L]);
    swap(poz[H[1]],poz[H[L]]);
    L--;
    int p=1;
    while((2*p<=L and key[H[p]]>key[H[2*p]]) or (2*p+1<=L and key[H[p]]>key[H[2*p+1]]))
    {
        if(2*p+1>L or key[H[2*p]]<key[H[2*p+1]])
        {
            swap(H[p],H[2*p]);
            swap(poz[H[p]],poz[H[2*p]]);
            p=p*2;
        }
        else
        {
            swap(H[p],H[2*p+1]);
            swap(poz[H[p]],poz[H[2*p+1]]);
            p=p*2+1;
        }
    }
    return rad;
}

void push_apm(int nod)
{
    fr[nod]=true;
    int vecin, cost;
    for(int i=0;i<v[nod].size();i++)
    {
        vecin=v[nod][i].first;
        cost=v[nod][i].second;
        if(fr[vecin]==false)
        {
            if(cost<key[vecin])
            {
                key[vecin]=cost;
                P[vecin]=nod;
                actualizare(poz[vecin]);
            }
        }
    }
}

void Prim(int start)
{
    for(int i=1;i<=n;i++)
        key[i]=inf;
    key[start]=0;
    push_apm(start);

    for(int i=1;i<=n;i++)
    {
        if(i!=start)
            push_MinHeap(i);
    }

    for(int i=1;i<n;i++)
    {
        int x=radacina_MinHeap();
        push_apm(x);
        total+=key[x];
    }
}

void afisare()
{
    fout<<total<<'\n';
    fout<<n-1<<'\n';
    for(int i=2;i<=n;i++)
    {
        fout<<P[i]<<' '<<i<<'\n';
    }
    fout.close();
}

int main()
{
    citire();
    Prim(1);
    afisare();
    return 0;
}