Cod sursa(job #155578)

Utilizator mithyPopovici Adrian mithy Data 12 martie 2008 00:18:19
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <stdio.h>
#include <vector>
#define NMax 50005
#define INF 50000

int T, n, m, s, lg;
int distA[NMax], distB[NMax], uz[NMax];
std::vector<int> a[NMax], cost[NMax];

struct muchie
{ int x, y, cost; } heap[NMax];

void rez();
void dijkstra();

// heap
void clearHeap();
void upHeap( int x );
void downHeap( int x );
void push( muchie x );
void swap( muchie &x, muchie &y );
int getL( int x );
int getR( int x );
int getP( int x );
muchie pop();

int main()
{
	rez();
	return 0;
}
void dijkstra()
{
	int i, j, ok = 1, lg;
	muchie aux, aux2;

	for (i=1; i<=n; i++)
	{
		uz[i]    = 0;
		distA[i] = INF;
	}
	clearHeap();

	lg = a[s].size();
	for (i=0; i<lg; i++)
	{
		distA[a[s][i]] = cost[s][i];
		aux.x = s;
		aux.y = a[s][i];
		aux.cost = cost[s][i];
		push( aux );
	}

	distA[s] = 0;

	for (i=1; i<n; i++)
	{
		aux = pop();

		uz[aux.y] = 1;

		lg = a[aux.y].size();
		for (j=0; j<lg; j++)
			if ( !uz[a[aux.y][j]] && distA[a[aux.y][j]] > distA[aux.y] + cost[aux.y][j] )
			{
				distA[a[aux.y][j]] = distA[aux.y] + cost[aux.y][j];
				aux2.x    = aux.y;
				aux2.y    = a[aux.y][j];
				aux2.cost = cost[aux.y][j];
				push(aux2);
			}
	}

	for (i=1; i<=n && ok; i++)
 		if ( distA[i] != distB[i] )
 			ok = 0;

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

}
void rez()
{
	int i, j, x, y, z;

	freopen( "distante.in", "rt", stdin );
	freopen( "distante.out", "wt", stdout );

	scanf( "%d", &T );
	for (i=0; i<T; i++)
	{
		scanf( "%d %d %d", &n, &m, &s );
		for (j=1; j<=n; j++)
		{
			a[j].clear();
			cost[j].clear();
		}

		for (j=1; j<=n; j++)
			scanf( "%d", &distB[j] );
		for (j=0; j<m; j++)
		{
			scanf( "%d %d %d", &x, &y, &z );
			a[x].push_back( y );
			cost[x].push_back( z );
			a[y].push_back( x );
			cost[y].push_back( z );
		}
		dijkstra();
	}
}
// heap
void clearHeap()
{
	muchie aux;

	aux = pop();
	while ( aux.cost != -1 )
		aux = pop();
}
void upHeap( int x )
{
	int p;

	while ( x > 1 )
	{
		p = getP( x );
		if ( heap[p].cost > heap[x].cost )
			swap(  heap[p], heap[x] );
		x = p;
	}
}
void downHeap( int x )
{
	int c1, c2, sel;

	while ( x * 2 <= lg )
	{
		c1 = getL( x );
		c2 = getR( x );

		sel = (heap[c1].cost<heap[c2].cost)?c1:c2;

		if ( heap[sel].cost < heap[x].cost )
			swap( heap[sel], heap[x] );

		x = sel;
	}
}
void push( muchie x )
{
	heap[++lg] = x;
	upHeap(lg);
}
void swap( muchie &x, muchie &y )
{
	muchie z;
	z = x;
	x = y;
	y = z;
}
int getL( int x )
{ return x*2; }
int getR( int x )
{ return x*2+1; }
int getP( int x )
{ return x/2; }
muchie pop()
{
	muchie aux;
	
	if ( lg == 0 )
		aux.cost = -1;
	else
	{
		aux     =  heap[1];
		heap[1] = heap[lg--];

		downHeap(1);
	}
	return aux;
}