Cod sursa(job #863758)

Utilizator costi_.-.Costinnel costi_.-. Data 24 ianuarie 2013 00:58:55
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <fstream>
#include <iostream>
#define nmax 2001
#define inf 0x3f3f3f3f
using namespace std;

struct nod_lista{
    int vecin,cost;
    nod_lista *link;};

nod_lista *G[nmax],*Last[nmax];
//Pentru heap
int Hp[nmax],Frunza[nmax];
//Pt Dijkstra
int D[nmax];
//Problema
int V[20];
int N,M,K,L,nHP;


void adauga(int unde,int ce,int cat)
{
    nod_lista *q=new nod_lista;

    q->vecin=ce;
    q->cost=cat;
    q->link=NULL;

    if(!G[unde])
    G[unde]=Last[unde]=q;
    else
    {
        Last[unde]->link=q;
        Last[unde]=q;
    }
    //A[unde][ce]=cat;
}

void citeste()
{
    ifstream f("ubuntzei.in");
    int i,x,y,z;

    f>>N>>M>>K;
    for(i=1;i<=K;i++)
    f>>V[i];

    for(i=1;i<=M;i++)
    {
        f>>x>>y>>z;
        adauga(x,y,z);
        adauga(y,x,z);
    }

    f.close();
}

//Proceduri heap

void intersch(int frunza1,int frunza2)
{
    int aux;
    aux=Hp[frunza1];
    Hp[frunza1]=Hp[frunza2];
    Hp[frunza2]=aux;

    aux=Frunza[Hp[frunza1]];
    Frunza[Hp[frunza1]]=Frunza[Hp[frunza2]];
    Frunza[Hp[frunza2]]=aux;
}

void coboara(int frunza)
{
    int fiu;
    do
    {
        fiu = 0;
        if((frunza<<1)<=nHP)
        {
            fiu=frunza<<1;
            if(fiu+1<=nHP && D[Hp[fiu+1]]<D[Hp[fiu]])
            ++fiu;

            if(D[Hp[frunza]]>D[Hp[fiu]])
            {
                intersch(fiu,frunza);
                frunza=fiu;
            }
            else
            fiu = 0;
        }
    }while(fiu);
}

void infiltrare(int frunza)
{
    if(frunza>1)
      if(D[Hp[frunza]]>D[Hp[frunza/2]])
        return;
      else
      {
          intersch(frunza,frunza/2);
          infiltrare(frunza/2);
      }
}

int Dijkstra(int S,int Dest)
{
    nod_lista *q;
    int nodmin,i;

    for(i=1;i<=N;i++)
    {
        D[i]=inf;
        Hp[i]=Frunza[i]=i;
    }

    nHP=N;
    D[S]=0;
    intersch(1,S);

    for(i=1;i<=N;i++)
    {
        nodmin=Hp[1];
        intersch(1,nHP);
        --nHP;
        coboara(1);

        q=G[nodmin];
        while(q)
        {
            if(D[q->vecin]>D[nodmin]+q->cost)
            {
                D[q->vecin]=D[nodmin]+q->cost;
                if(q->vecin == Dest)
                //return D[Dest];
                infiltrare(Frunza[q->vecin]);
            }
            q=q->link;
        }
    }

    return D[Dest];
}

void rezolva()
{
    int i;
    L+=Dijkstra(1,V[1]);
    for(i=2;i<=K-1;i++)
    L+=Dijkstra(V[i],V[i+1]);

    L+=Dijkstra(V[K],N);
}

void scrie()
{
    ofstream g("ubuntzei.out");

    g<<L<<'\n';
    g.close();
}
int main()
{
    citeste();
    rezolva();
    scrie();
    return 0;
}