Cod sursa(job #1105024)

Utilizator Stefanescu_MihaiStefanescu Mihai-Nicolae Stefanescu_Mihai Data 11 februarie 2014 13:01:11
Problema Algoritmul lui Dijkstra Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.63 kb
#include <cstdio>
#include <vector>

using namespace std;

#define MaxN 50050

vector <int>vec[MaxN];
vector <int>mcost[MaxN];
int nrvec[MaxN];

int Heap[MaxN], HToV[MaxN], VToH[MaxN];
int cost[MaxN];
int nrheap;

char visited[MaxN];

void Heap_Swap( int nod1, int nod2 )
{
    int dummy = Heap[nod1];
    Heap[nod1] = Heap[nod2];
    Heap[nod2] = dummy;

    dummy = HToV[nod1];
    HToV[nod1] = HToV[nod2];
    HToV[nod2] = dummy;

    VToH[HToV[nod1]] = nod1;
    VToH[HToV[nod2]] = nod2;
}

void Heap_Down( int nod )
{
    while (true)
    {
        if ( nod*2+1 > nrheap )
        {
            if ( nod*2 > nrheap )
                break;
            else
            {
                if ( Heap[nod*2] < Heap[nod] )
                {
                    Heap_Swap( nod, nod*2 );
                    nod = nod*2;
                    continue;
                }
                else
                    break;
            }
        }
        else
        {
            if ( Heap[nod*2] < Heap[nod] )
            {
                if ( Heap[nod*2+1] < Heap[nod*2] )
                {
                    Heap_Swap( nod, nod*2+1 );
                    nod = nod*2+1;
                    continue;
                }
                else
                {
                    Heap_Swap( nod, nod*2 );
                    nod = nod*2;
                    continue;
                }
            }
            else
            {
                if ( Heap[nod*2+1] < Heap[nod] )
                {
                    Heap_Swap( nod, nod*2+1 );
                    nod = nod*2+1;
                    continue;
                }
                else
                    break;
            }
        }
    }
}

void Heap_Up( int nod )
{
    while ( Heap[nod] < Heap[nod/2] )
    {
        Heap_Swap( nod/2, nod );
        nod = nod/2;
    }
}

void Heap_Add( int vnod )
{
    Heap[++nrheap] = cost[vnod];
    HToV[nrheap] = vnod;
    VToH[vnod] = nrheap;

    Heap_Up( nrheap );
}

void Heap_RemoveFirst()
{
    Heap_Swap( 1, nrheap-- );

    Heap_Down( 1 );
}

void Heap_Update( int nod )
{
    Heap[nod] = cost[HToV[nod]];

    if ( Heap[nod] < Heap[nod/2] )
        Heap_Up( nod );
    else
        Heap_Down( nod );
}


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

    int n, m;
    int x, y, c;

    int i, nod;

    Heap[0] = -1;

    scanf( "%d %d\n", &n, &m );

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

        vec[x].push_back(y);
        mcost[x].push_back(c);
        ++nrvec[x];

        vec[y].push_back(x);
        mcost[y].push_back(c);
        ++nrvec[y];
    }

    Heap_Add( 1 );

    while ( nrheap )
    {
        nod = HToV[1];

        for ( i = 0; i < nrvec[nod]; ++i )
        {
            if ( visited[vec[nod][i]] == 1 )
                continue;
            if ( !visited[vec[nod][i]] )
            {
                cost[vec[nod][i]] = cost[nod] + mcost[nod][i];
                visited[vec[nod][i]] = 2;
                Heap_Add( vec[nod][i] );
                continue;
            }
            if ( cost[nod] + mcost[nod][i] < cost[vec[nod][i]] )
            {
                cost[vec[nod][i]] = cost[nod] + mcost[nod][i];
                Heap_Update( VToH[vec[nod][i]] );
            }
        }

        visited[nod] = 1;
        Heap_RemoveFirst();
    }

    for ( i = 2; i <= n; ++i )
        printf( "%d ", cost[i] );
    printf( "\n" );

    fclose( stdin );
    fclose( stdout );

    return 0;
}