Cod sursa(job #970020)

Utilizator smaraldaSmaranda Dinu smaralda Data 5 iulie 2013 21:11:24
Problema Arbore partial de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
#include<vector>
#include<cstdio>
#define NMAX 200000
using namespace std;

int n,m,pos[NMAX+5];

struct EDGE  {   int v,v1,c;   };

vector <EDGE> graph[NMAX+5];
vector < pair <int, int> > res;
EDGE dmin[NMAX+5]; int sz;

EDGE make (int a, int b, int c)
{
    EDGE res={a,b,c};
    return res;
}

void swap (int pos1, int pos2)
{
    EDGE aux1; int aux2;
    aux2=pos[dmin[pos1].v];  pos[dmin[pos1].v]=pos[dmin[pos2].v]; pos[dmin[pos2].v]=aux2;
    aux1=dmin[pos1]; dmin[pos1]=dmin[pos2]; dmin[pos2]=aux1;
}

void up (int poz)
{
    while(poz>1 && dmin[poz].c < dmin[poz/2].c)
        {
            swap(poz,poz/2);
            poz>>=1;
        }
}

void down (int poz)
{
    int minim;
    while(1)
        {
            minim=poz;
            if(poz*2 <=sz && dmin[poz*2].c < dmin[minim].c)
                minim=poz*2;
            if(poz*2+1 <=sz && dmin[poz*2+1].c < dmin[minim].c)
                minim=poz*2+1;
            if(minim==poz)
                return;
            swap(poz,minim);
        }
}

void baga (int nod, int v, int val)
{
    dmin[++sz]=make(nod,v,val);
    pos[nod]=sz;
    up(sz);
}

void scoate()
{
    pos[dmin[1].v]=-1;
    dmin[1]=dmin[sz];
    sz--;
    if(sz)
        pos[dmin[1].v]=1;
    down(1);
}

void update (int poz, int v, int val)
{
    dmin[poz].c=val;
    dmin[poz].v1=v;
    up(poz);
}

int main()
{
    freopen("apm.in","r",stdin);
    freopen("apm.out","w",stdout);
    int i,x,y,c,pas=0,cost,v;
    scanf("%d%d",&n,&m);

    for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&c);
            graph[x].push_back(make(y,x,c));
            graph[y].push_back(make(x,y,c));
        }

    baga(1,0,0);
    cost=0;

    while(sz)
        {
            if(pas)
                res.push_back(make_pair(dmin[1].v,dmin[1].v1));
            pas=1;
            v=dmin[1].v;
            cost+=dmin[1].c;
            scoate();
            for(i=0;i<graph[v].size();i++)
                if(pos[graph[v][i].v]!=-1)
                    {
                        if(pos[graph[v][i].v]==0)
                            baga(graph[v][i].v,v,graph[v][i].c);
                        else
                            if(dmin[pos[graph[v][i].v]].c>graph[v][i].c)
                                update(pos[graph[v][i].v], v, graph[v][i].c);
                    }
        }
    printf("%d\n%d\n",cost,n-1);
    for(i=0;i<res.size();i++)
        printf("%d %d\n",res[i].first,res[i].second);
    return 0;
}