Cod sursa(job #1646189)

Utilizator andi12Draghici Andrei andi12 Data 10 martie 2016 15:22:18
Problema Arbore partial de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
#include <cstdio>

using namespace std;
const int N=200001;
const int M=400001;
int lst[N],urm[M],vf[M],cost[N],d[N],h[N],poz[M],pred[M];
int p,n,m,nh;
void ad(int x,int y,int c)
{
    p++;
    vf[p]=y;
    urm[p]=lst[x];
    lst[x]=p;
    cost[p]=c;
}
void schimba(int x,int y)
{
    int aux=h[x];
    h[x]=h[y];
    h[y]=aux;
    poz[h[x]]=x;
    poz[h[y]]=y;
}
void urca(int x)
{
    if(x==1)
        return ;
    if(d[h[x/2]]>d[h[x]])
    {
        schimba(x,x/2);
        urca(x/2);
    }
}
void coboara(int x)
{
    int bun,st=2*x,dr=2*x+1;
    if(st>nh) return ;
    bun=st;
    if(dr<=nh && d[h[st]]>d[h[dr]]) bun=dr;
    if(d[h[bun]]<d[h[x]])
    {
        schimba(bun,x);
        coboara(bun);
    }
}
int scoate()
{
    int a=h[1];
    schimba(1,nh);
    urca(1);
    coboara(1);
    nh--;
    poz[a]=-1;
    return a;
}
int main()
{
    FILE *in,*out;
    in=fopen("apm.in","r");
    out=fopen("apm.out","w");
    int i,j,c,x,y,total=0;
    fscanf(in,"%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        fscanf(in,"%d%d%d",&x,&y,&c);
        ad(x,y,c);
        ad(y,x,c);
    }
    for(i=1;i<=n;i++)
    {
        d[i]=9999999;
        h[i]=i;
        poz[i]=i;
    }
    d[1]=0;
    nh=n;
    while(nh!=0)
    {
        x=scoate();
        p=lst[x];
        while(p!=0)
        {
            y=vf[p];
            c=cost[p];
            if(c<d[y] && poz[y]!=-1)
            {
                d[y]=c;
                urca(poz[y]);
                pred[y]=x;
            }
            p=urm[p];
        }
    }
    for(i=1;i<=n;i++)
        total=total+d[i];
    fprintf(out,"%d\n%d\n",total+1,n-1);
    for(i=2;i<=n;i++)
        fprintf(out,"%d %d\n",i,pred[i]);
    return 0;
}