Cod sursa(job #1284060)

Utilizator roxyroxy2011Luca Roxana roxyroxy2011 Data 6 decembrie 2014 10:47:39
Problema Arbore partial de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.3 kb
#include <fstream>
#define NMAX 100004
#define MMAX 100004

using namespace std;

ifstream cin("apm.in");
ofstream cout("apm.out");

struct Muchie{int x,y,c;} G[MMAX];

int H[MMAX],n,m,mm,h[NMAX],tata[NMAX];
int A[NMAX],cost;//indiciile selectate in APM

void citire();
void creare();
void combinare(int);
int extragere_minim();
void kruskal();
void afisare();
void Union(int,int);
int Find(int);

int main()
{
    citire();
    kruskal();
    afisare();
    cin.close();cout.close();
    return 0;
}

void kruskal()
{
    int nr=0,nmin,cx,cy;
    mm=m;
    creare();
    while (nr<n-1)
    {
        nmin=extragere_minim();
        cx=Find(G[nmin].x);
        cy=Find(G[nmin].y);
        if (cx!=cy)
        {
            nr++;
            A[nr]=nmin;
            cost+=G[nmin].c;
            Union(cx,cy);
        }
    }
}

void afisare()
{
    int i;
    cout<<cost<<'\n';
    cout<<n-1<<'\n';
    for (i=1;i<n;i++)
        cout<<G[A[i]].x<<' '<<G[A[i]].y<<'\n';
}

void citire()
{
    int i;
    cin>>n>>m;
    for (i=1;i<=m;i++)
    {
        H[i]=i;
        cin>>G[i].x>>G[i].y>>G[i].c;
    }
}

int Find(int x)
{
    int rad=x,aux;
    //caut radacina
    while (tata[rad]!=0)
        rad=tata[rad];
    while (tata[x])
    {
        aux=tata[x];
        tata[x]=rad;
        x=aux;
    }
    return rad;
}

void Union(int i,int j)
{
    //il fac pe x fiu ai lui y
    //i si j sunt radacinile arborilor care reprezinta radacina x si y
    if (h[i]<h[j])
        tata[i]=j;
    else
    {
        tata[j]=i;
        if (h[i]==h[j])
            h[i]++;
    }
}

void combinare(int i)
//se combina nodul H[i] cu heapurile de radacinile 2*i si 2*i+1 obtinand n heap cu radacinile H[i]
{
    int x=H[i],tata,fiu;
    tata=i;fiu=i<<1;
    while (fiu<=mm)
    {
        if (fiu+1<=mm && G[H[fiu+1]].c<G[H[fiu]].c) fiu++;
        // fiu cel mai mic fiu dintre fii lui x
        if (G[H[fiu]].c<G[x].c)
        {
            H[tata]=H[fiu];
            tata=fiu;
            fiu=tata<<1;
        }
        else break;
    }
    H[tata]=x;
}

void creare()
{
    int i;
    for (i=mm/2;i>0;i--)
        combinare(i);
}

int extragere_minim()
{
    int val=H[1];
    H[1]=H[mm];
    mm--;
    combinare(1);
    return val;
}