Cod sursa(job #214950)

Utilizator ProtomanAndrei Purice Protoman Data 17 octombrie 2008 00:20:03
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <stdio.h>
#include <algorithm>
#define sec second
#define fir first
#define mx 11000

using namespace std;

struct nod
{
	int nr, d;
	nod *ua;
} *l[mx], *p;
pair <int, int> hp[mx];
int dist[mx], eih[mx], sd[mx];
int t, s, n, m, lmin, dimh, n1, n2, c;

void clad(int t, int f, int cost)
{
	nod *p = new nod;
	p->nr = n2;
	p->d = cost;
	p->ua = l[t];
	l[t] = p;
}

void swap(int i, int j)
{
	pair <int, int> aux = hp[i];
	hp[i] = hp[j];
	hp[j] = aux;
	eih[hp[i].sec] = i;
	eih[hp[j].sec] = j;
}

void heapup(int i)
{
	if (i > 1)
		if (hp[i].fir < hp[i / 2].fir)
		{
			swap(i, i / 2);
			heapup(i / 2);
		}
}

void heapdown(int i)
{
	if (i << 1 <= dimh)
	{
		int f = i << 1;
		if (f < dimh && hp[f + 1].fir < hp[f].fir)
			f++;
		if (hp[i].fir > hp[f].fir)
		{
			swap(i, f);
			heapdown(f);
		}
	}
}

int main()
{
	freopen("distante.in","r",stdin);
	freopen("distante.out","w",stdout);
	for (scanf("%ld", &t); t; t--)
	{
		scanf("%ld %ld %ld", &n, &m, &s);
		memset(sd, 0, sizeof(sd));
		for (int i = 1; i < mx; i++)
		{
			dist[i] = LONG_MAX;
			hp[i].fir = 0;
			hp[i].sec = 0;
		}
		dist[s] = 0;
		for (int i = 1; i <= n; i++)
			scanf("%ld", &sd[i]);
		for (int i = 1; i <= m; i++)
		{
			scanf("%ld %ld %ld", &n1, &n2, &c);
			clad(n1, n2, c);
			clad(n2, n1, c);
		}
		for (nod *p = l[s]; p; p = p->ua)
		{
			dimh++;
			dist[p->nr] = p->d;
			hp[dimh].fir = p->d;
			hp[dimh].sec = p->nr;
			eih[p->nr] = dimh;
			heapup(dimh);
		}
		int minim = 1;
		for (; minim; )
		{
			minim = hp[1].sec;
			lmin = hp[1].fir;
			for (nod *p = l[minim]; p; p = p->ua)
				if (p->d + lmin < dist[p->nr])
				{
					dist[p->nr] = p->d + lmin;
					if (!eih[p->nr])
					{
						dimh++;
						eih[p->nr] = dimh;
						hp[dimh].fir = dist[p->nr];
						hp[dimh].sec = p->nr;
					}
					heapup(eih[p->nr]);
				}
			hp[1] = hp[dimh];
			eih[hp[1].sec] = 1;
			dimh--;
			heapdown(1);
		}
		bool ok = 1;
		for (int i = 1; i <= n; i++)
			if (dist[i] != sd[i])
				ok = 0;
		if (ok)
			printf("DA\n");
		else printf("NU\n");
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}