Cod sursa(job #891196)

Utilizator paulbotabota paul paulbota Data 25 februarie 2013 14:38:24
Problema Arbore partial de cost minim Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <cstdio>
#include <algorithm>
#define MAXN 200010
#define INF 1<<30

using namespace std;

struct graf
{
    int nod,cost;
    graf *next;
};

graf *a[MAXN];
int n,m,sum,h[2*MAXN+100],poz[MAXN],k,tata[MAXN],c[MAXN],apm[MAXN],ap,apmt[MAXN];

void swap(int x,int y)
{
    int aux=h[x];
    h[x]=h[y];
    h[y]=aux;
    poz[h[x]]=x;
    poz[h[y]]=y;
}

void upheap(int i)
{
    while(i>1 && c[h[i/2]]>c[h[i]])
    {
        swap(i,i/2);
        i=i/2;
    }
}

void downheap(int i)
{
    int stg,dr,max=i;
    stg=2*i;
    dr=2*i+1;
    if(stg<=k && c[h[stg]]<c[h[i]])
        max=stg;
    if(dr<=k && c[h[dr]]<c[h[max]])
        max=dr;
    if(max!=i)
    {
        swap(i,max);
        downheap(max);
    }
}

void insert_heap(int key)
{
    h[++k]=key;
    poz[key]=k;
    upheap(k);
}

int extract_min()
{
    int min=h[1];
    swap(1,k);
    k--;
    downheap(1);
    poz[min]=0;
    return min;
}

void add(int x,int y,int z)
{
    graf *q=new graf;
    q->nod=y;
    q->cost=z;
    q->next=a[x];
    a[x]=q;
}
inline void read()
{
    freopen("apm.in","r",stdin);
    freopen("apm.out","w",stdout);
    int x,y,z;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
}

void insert(int i)
{
    graf *q;
    for(q=a[i];q;q=q->next)
    {
        c[q->nod]=min(c[q->nod],q->cost);
        if(c[q->nod]==q->cost)
            tata[q->nod]=i;
    }
}

int main()
{
    read();
    int i;
    for(i=1;i<=n;i++)
        c[i]=INF;
    c[1]=0;
    insert(1);
    for(i=2;i<=n;i++)
    {
        insert_heap(i);
    }

    for(i=1;i<n;i++)
    {
        int min=extract_min();
        insert(min);
        sum+=c[min];
        apm[++ap]=min;
        apmt[ap]=tata[min];
        graf *q=a[min];
        for(;q;q=q->next)
        {
            if(poz[q->nod])
                upheap(poz[q->nod]);
        }
    }
    printf("%d\n%d\n",sum,n-1);
    for(i=1;i<=ap;i++)
        printf("%d %d\n",apm[i],apmt[i]);
    return 0;
}