Cod sursa(job #1090130)

Utilizator Stefanescu_MihaiStefanescu Mihai-Nicolae Stefanescu_Mihai Data 22 ianuarie 2014 13:04:14
Problema Algoritmul lui Dijkstra Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.39 kb
#include <cstdio>
#include <vector>

#include <cmath>

using namespace std;

#define MAXN 50100

vector <int>vec[MAXN];
vector <int>cost[MAXN];

int heap[MAXN];
int vtoheap[MAXN];
int heaptov[MAXN];
int cost1[MAXN];
bool visited[MAXN];
int v[MAXN];

int nrheap;

void HeapSwap( int nod1, int nod2 )
{
    int dummy;

    dummy = heap[nod1];
    heap[nod1] = heap[nod2];
    heap[nod2] = dummy;

    vtoheap[heaptov[nod1]] = nod2;
    vtoheap[heaptov[nod2]] = nod1;

    dummy = heaptov[nod1];
    heaptov[nod1] = heaptov[nod2];
    heaptov[nod2] = dummy;
}

void HeapUp( int nod )
{
    bool ok = 1;
    while ( ok )
    {
        ok = 0;
        if ( heap[nod] < heap[nod/2] )
        {
            HeapSwap( nod, nod/2 );
            nod /= 2;
            ok = 1;
        }
    }
}

void HeapDown( int nod )
{
    bool ok = 1;
    while ( ok )
    {
        ok = 0;
        if ( ( heap[nod] > heap[nod*2] ) && ( nod*2 <= nrheap ) )
        {
            if ( ( heap[nod*2] > heap[nod*2+1] ) && ( nod*2+1 <= nrheap ) )
            {
                HeapSwap( nod, nod*2+1 );
                nod = nod*2+1;
                ok = 1;
            }
            else
            {
                HeapSwap( nod, nod*2 );
                nod *= 2;
                ok = 1;
            }
        }
        else
        {
            if ( ( heap[nod] > heap[nod*2+1] ) && ( nod*2+1 <= nrheap ) )
            {
                HeapSwap( nod, nod*2+1 );
                nod = nod*2+1;
                ok = 1;
            }
        }
    }
}


void HeapAdd( int vpoz )
{
    heap[++nrheap] = cost1[vpoz];
    heaptov[nrheap] = vpoz;
    vtoheap[vpoz] = nrheap;

    HeapUp( nrheap );
}

void HeapRemove( int nod )
{
    HeapSwap( nod, nrheap-- );

    if ( heap[nod] < heap[nod/2] )
    {
        HeapUp( nod );
    }
    else
    {
        HeapDown( nod );
    }
}

void HeapUpdate( int nod )
{
    heap[nod] = cost1[heaptov[nod]];

    if ( heap[nod] < heap[nod/2] )
    {
        HeapUp( nod );
    }
    else
    {
        HeapDown( nod );
    }
}

int main()
{
    freopen( "dijkstra.in", "r", stdin );
    freopen( "dijkstra.out", "w", stdout );

    int nrm, nrnod, i;

    scanf( "%d %d\n", &nrnod, &nrm );


    int x, y, c;
    for ( i = 0; i < nrm; ++i )
    {
        scanf( "%d %d %d\n", &x, &y, &c );

        vec[x].push_back(y);
        cost[x].push_back(c);
        ++v[x];
    }

    heap[0] = -1;

    cost1[1] = 0;
    HeapAdd( 1 );

    int nod;

    while ( nrheap > 0 )
    {
        nod = heaptov[1];
        for ( i = 0; i < v[nod]; ++i )
        {
            if ( visited[vec[nod][i]] )
                continue;

            if ( !cost1[vec[nod][i]] )
            {
                cost1[vec[nod][i]] = cost1[nod] + cost[nod][i];
                HeapAdd( vec[nod][i] );

                continue;
            }

            if ( cost1[vec[nod][i]] > cost1[nod] + cost[nod][i] )
            {
                cost1[vec[nod][i]] = cost1[nod] + cost[nod][i];

                HeapUpdate( vtoheap[vec[nod][i]] );
            }
        }

        visited[heaptov[1]] = 1;
        HeapRemove( 1 );
    }


    for ( i = 2; i <= nrnod; ++i )
    {
        printf( "%d ", cost1[i] );
    }

    printf( "\n" );


    fclose( stdin );
    fclose( stdout );

    return 0;
}