Cod sursa(job #442396)

Utilizator DranaXumAlexandru Dumitru Paunoiu DranaXum Data 14 aprilie 2010 12:55:41
Problema Algoritmul lui Dijkstra Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.51 kb
#include<iostream>
#include<cstring>
#include<vector>

#define NMAX 100020
#define INF (1<<31)-1

using namespace std;

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

int drmin=INF;
int n,m;
int aa,bb,cc;

int viz[NMAX],h[NMAX];
int dr[NMAX];
int para[NMAX],parb[NMAX],parc[NMAX];

int lnaa,lnbb,lncc;

void read()
{
    drmin=INF;
    int i,x,y,c;
    scanf("%d%d",&n,&m);
    scanf("%d%d%d",&aa,&bb,&cc);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&c);
        G[x].push_back(make_pair(y,c));
        G[y].push_back(make_pair(x,c));
    }
}

int k;

void swap(int a,int b){int aux; aux=h[a]; h[a]=h[b]; h[b]=aux;}

void upheap(int what)
{
    int tata;
    while ( what > 1 )
    {
        tata = what >> 1;

        if ( dr[ h[tata] ] > dr[ h[what] ] )
        {
            viz[ h[what] ] = tata;
            viz[ h[tata] ] = what;

            swap(tata, what);

            what = tata;
        }
        else
            what = 1;
    }
}

void downheap(int what)
{
    int f;
    while ( what <= k )
    {
        f = what;
        if ( (what<<1) <= k )
        {
            f = what << 1;
            if ( f + 1 <= k )
                if ( dr[ h[f + 1] ] < dr[ h[f] ] )
                    ++f;
        }
        else
            return;

        if ( dr[ h[what] ] > dr[ h[f] ] )
        {
            viz[ h[what] ] = f;
            viz[ h[f] ] = what;

            swap(what, f);

            what = f;
        }
        else
            return;
    }
}

void dijkstra(int src,int ln[],int par[])
{
    int i;
    k=1;
    for(int i=1;i<=n;i++)
        dr[i]=INF,viz[i]=-1;
    dr[src]=0;
    viz[src]=1,ln[src]=1;
    h[1]=src; par[src]=-1;
    while(k)
    {
        int min=h[1];
        swap(1,k);
        viz[h[1]]=1;
        k--;
        downheap(1);
        for(vector<pair<int,int> >::iterator it=G[min].begin();it!=G[min].end();it++)
        {
            int nod=(*it).first;
            int cost=(*it).second;
            if(dr[nod]>dr[min]+cost && min!=nod)
            {
                dr[nod]=dr[min]+cost;
                ln[nod]=ln[min]+1;
				par[nod]=min;	
                if(viz[nod]!=-1)
                {
                    upheap(viz[nod]);
                }
                else
                {
                    h[++k]=nod;
                    viz[h[k]]=k;
                    upheap(k);
                }
            }
        }
    }
}

int srcm;

int lna[NMAX],lnb[NMAX],lnc[NMAX];

void solve()
{
    int dra[NMAX],drb[NMAX],drc[NMAX];

    drmin=INF;

    dijkstra(aa,lna,para);
    memcpy(dra,dr,sizeof(dr));

    dijkstra(bb,lnb,parb);
    memcpy(drb,dr,sizeof(dr));

    dijkstra(cc,lnc,parc);
    memcpy(drc,dr,sizeof(dr));

    for(int i=1;i<=n;i++)
    {
        if(dra[i]!=INF && drb[i]!=INF && drc[i]!=INF)
        {
            if(drmin>dra[i]+drb[i]+drc[i])
            {
                drmin=dra[i]+drb[i]+drc[i];
                srcm=i;
                lnaa=lna[i],lnbb=lnb[i],lncc=lnc[i];
            }
        }
    }
}

void afis(int p,int park[],int ln)
{
    for(int i=1;i<=ln;i++,p=park[p])
		printf("%d ",p);
    printf("\n");
}

void write()
{
    printf("%d\n",drmin);
    printf("%d ",lnaa),afis(srcm,para,lnaa);
    printf("%d ",lnbb),afis(srcm,parb,lnbb);
    printf("%d ",lncc),afis(srcm,parc,lncc);
}

int main()
{
    freopen("trilant.in","r",stdin);
    freopen("trilant.out","w",stdout);
    read(); solve(); write();
    return 0;
}