Cod sursa(job #1097733)

Utilizator drobertDumitru Robert drobert Data 3 februarie 2014 21:35:17
Problema Distante Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <fstream>
using namespace std;
ifstream cin( "distante.in" );
ofstream cout( "distante.out" );

int n, m, s, t, r[ 50001 ], ok, inf, x, y, c, k;
int poz[ 50001 ], d[ 50001 ], h[ 50001 ], minim;
struct graf
{
	int nod, cost;
	graf *next;
}*a[ 50001 ], *q;

void swap( int x,int y )
{
	int aux;
	aux = h[ x ];
	h[ x ] = h[ y ];
	h[ y ] = aux;
}

void upheap( int nod )
{
	int t;
	while ( nod > 1 )
	{
		t = nod / 2;
		if ( d[ h[ t ] ] > d[ h[ nod ] ] )
		{
			poz[ h[ t ] ] = nod;
			poz[ h[ nod ] ] = t;
			swap( t,nod );
			nod = t;
		}
		else break;
	}
}

void downheap( int nod )
{
	int f;
	while ( nod <= k )
	{
		f = nod;
		if ( nod * 2 <= k )
		{
			f = nod * 2;
			if ( f + 1 <= k )
				if ( d[ h[ f + 1 ] ] < d[ h[ f ] ] )
					f++;
		}
		else return;
		if ( d[ h[ nod ] ] > d[ h[ f ] ] )
		{
			poz[ h[ f ] ] = nod;
			poz[ h[ nod ] ] = f;
			swap( f,nod );
			nod = f;
		}
		else return;
	}
}

int main()
{
	int i, j;
	cin >> t;
	inf = 2000000000;
	for ( ; t; t-- )
	{
		cin >> n >> m >> s;
		for ( i = 1; i <= n; i++ )
		{
			a[ i ] = NULL;
			d[ i ] = inf;
			poz[ i ] = 0;
		}
		d[ s ] = 0;
		for ( i = 1; i <= n; i++ )
			cin >> r[ i ];
		for ( i = 1; i <= m; i++ )
		{
			cin >> x >> y >> c;
			q = new graf;
			q->nod = y;
			q->cost = c;
			q->next = a[ x ];
			a[ x ] = q;
			q = new graf;
			q->nod = x;
			q->cost = c;
			q->next = a[ y ];
			a[ y ] = q;
		}
		k = 0;
		h[ ++k ] = s;
		poz[ s ] = 1;
		while ( k )
		{
			minim = h[ 1 ];
			swap( 1,k );
			poz[ h[ 1 ] ] = 1;
			k--;
			downheap( 1 );
			q = a[ minim ];
			while ( q )
			{
				if ( d[ q->nod ] > d[ minim ] + q->cost )
				{
					d[ q->nod ] = d[ minim ] + q->cost;
					if ( poz[ q->nod ] )
						upheap( poz[ q->nod ] );
					else
					{
						h[ ++k ] = q->nod;
						poz[ q->nod ] = k;
						upheap( k );
					}
				}
				q = q->next;
			}
		}
		ok = 1;
		for ( i = 1; i <= n; i++ )
			if ( d[ i ] != r[ i ] )
			{
				ok = 0;
				break;
			}
		if ( ok ) cout << "DA" << '\n';
		else cout << "NU" << '\n';
	}
}