Cod sursa(job #4235)

Utilizator gigi_becaliGigi Becali gigi_becali Data 1 ianuarie 2007 17:24:02
Problema Distante Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <cstdio>
#include <vector>
#include <string>
#define oo 0x3f3f3f3f
#define left(i) (((i)<<1))
#define right(i) (((i)<<1)+1)
#define tata(i) ((i)>>1)
#define maxn 1<<16
using namespace std;

int H[maxn], d[maxn], t[maxn], T, n, m, poz[maxn], d1[maxn];

int nh;
struct nod{ int nd, w; nod(int _nd, int _w){ nd=_nd; w=_w;};};

vector< vector<nod> >a;

void swap(int i, int j)
{
	int aux=H[i]; H[i]=H[j]; H[j]=aux;
		poz[H[i]]=i; poz[H[j]]=j;
}

void upheap(int i)
{
	if(i<=1) return;
	if(d[H[i]]<d[H[tata(i)]]) swap(i, tata(i)), upheap(tata(i));
}

void downheap(int i)
{
	int min=i;
	
	if(left(i)<=nh && d[H[left(i)]]<d[H[i]]) min=left(i);
	if(right(i)<=nh && d[H[right(i)]]<d[H[min]]) min=right(i);
	if(min!=i) swap(min, i), downheap(min);
}
	


void dijkstra(int s)
{		
	int i, j;	
	
	memset(t, -1, sizeof(t));
	memset(d, oo, sizeof(d));
	memset(H, 0 , sizeof(H));
	d[s]=0;
	nh=0;
	for(i=1;i<=n;i++) poz[i]=i;
	for(i=1;i<=n;i++) { H[++nh]=i; upheap(nh);}
	
	while(nh)
	{
		int u=H[1];
		H[1]=H[nh]; poz[nh]=1;nh--;
		downheap(1);

		for(i=0;i<a[u].size();i++)
			if(d[u]+a[u][i].w<d[a[u][i].nd])
			{
				d[a[u][i].nd]=d[u]+a[u][i].w;
				t[a[u][i].nd]=u;
				upheap(poz[a[u][i].nd]);
			}
			
	}
	
}

int main()
{
	freopen("distante.in", "r", stdin);
	freopen("distante.out", "w", stdout);
	int i, j,p, q, w, s;
	scanf("%d", &T);
	for(i=1;i<=T;i++)
	{	
		a.clear();
		scanf("%d %d %d\n", &n, &m, &s);
		a.resize(n+1);
		for(j=1;j<=n;j++) scanf("%d ", d1+j);
		for(j=1;j<=m;j++)
		{
			scanf("%d %d %d\n", &p, &q, &w);
			a[p].push_back(nod(q, w));
			a[q].push_back(nod(p, w));
		}
		dijkstra(s);
		int ok=1;
		for(j=1;j<=n;j++) if(d1[j]!=d[j]){ ok=0; break;}
		if(ok) printf("DA\n");
			else printf("NU\n");
	}
	return 0;
}