Cod sursa(job #1250889)

Utilizator deea101Andreea deea101 Data 28 octombrie 2014 18:25:18
Problema Arbore partial de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include <fstream>
#include <vector>
#define NMAX 200001

using namespace std;
ifstream f("apm.in");
ofstream g("apm.out");

vector < pair <int, int> > G[NMAX],sol;
vector < int > h;

int dist[NMAX],ph[NMAX],t[NMAX];
int N,best=0;
bool in[NMAX];

void sift(int nod)
{
    int f1,f2,son=nod;

    do
    {
        nod=son;
        f1=2*nod; f2=2*nod+1;

        if(f1<h.size() && dist[h[f1]]<dist[h[son]]) son=f1;
        if(f2<h.size() && dist[h[f2]]<dist[h[son]]) son=f2;

        swap(h[son],h[nod]);
        ph[h[son]]=son;
        ph[h[nod]]=nod;

    }while(nod!=son);
}

void percolate(int nod)
{
    while(nod/2 && dist[h[nod]]<dist[h[nod/2]])
    {
        swap(h[nod],h[nod/2]);
        ph[h[nod]]=nod;
        ph[h[nod/2]]=nod/2;
        nod/=2;
    }
}
void adaugare(int val)
{
    h.push_back(val);
    ph[val]=h.size()-1;
    percolate(ph[val]);
}
int main()
{
    int M,i,x,y,d;

    f>>N>>M;
    while(M--)
    {
        f>>x>>y>>d;
        G[x].push_back(make_pair(y,d));
        G[y].push_back(make_pair(x,d));
    }

    h.push_back(1);
    dist[1]=0;
    t[1]=1;

    int nod;
    while(!h.empty())
    {
        nod=h.front();
        in[nod]=1;

        if(nod!=1)
        {
            sol.push_back(make_pair(nod,t[nod]));
            best+=dist[nod];
        }

        for(i=0;i<G[nod].size();i++)
        {
            y=G[nod][i].first;
            d=G[nod][i].second;

            if(!t[y])
            {
                dist[y]=d;
                t[y]=nod;
                adaugare(y);
            }
            else if(dist[y]>d && !in[y])
                {
                    dist[y]=d;
                    t[y]=nod;
                    percolate(ph[y]);
                }
        }

        h[0]=h[h.size()-1];
        ph[h[0]]=0;
        h.pop_back();
        sift(0);

    }

    g<<best<<'\n';
    g<<N-1<<'\n';
    for(i=0;i<sol.size();i++)
        g<<sol[i].first<<' '<<sol[i].second<<'\n';
}