Cod sursa(job #1105997)

Utilizator Stefanescu_MihaiStefanescu Mihai-Nicolae Stefanescu_Mihai Data 12 februarie 2014 12:36:20
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.32 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;

short 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( "distante.in", "r", stdin );
    freopen( "distante.out", "w", stdout );

    int n, m, s;

    short t, it;
    int x, y, c;

    int d[MaxN], i, nod;

    bool ok;

    Heap[0] = -1;

    int dummy;
    scanf( "%d\n", &dummy );
    t = (short)dummy;

    for ( it = 1; it <= t; ++it )
    {
        scanf( "%d %d %d\n", &n, &m, &s );

        for ( i = 1; i <= n; ++i )
            scanf( "%d ", &d[i] );

        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( s );
        ok = 1;
        while ( nrheap )
        {
            nod = HToV[1];

            for ( i = 0; i < nrvec[nod]; ++i )
            {
                if ( visited[vec[nod][i]] == it )
                    continue;
                if ( visited[vec[nod][i]] < it )
                {
                    cost[vec[nod][i]] = cost[nod] + mcost[nod][i];
                    visited[vec[nod][i]] = it + 16;
                    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] = it;
            if ( cost[nod] != d[nod] )
            {
                ok = 0;
                break;
            }

            Heap_RemoveFirst();
        }

        if ( ok )
            printf( "DA\n" );
        else
            printf( "NU\n" );

        for ( i = 1; i <= n; ++i )
        {
            vec[i].clear();
            mcost[i].clear();
            nrvec[i] = 0;
        }
        nrheap = 0;
    }

    fclose( stdin );
    fclose( stdout );

    return 0;
}