Cod sursa(job #279097)

Utilizator GagosGagos Radu Vasile Gagos Data 12 martie 2009 17:52:11
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef struct nod
{
	int info,dist;
	nod *next;
}*pnod;
pnod L[50003],g;
int a,b,c,n,m,t,cv,cd,hl,aux,s,i;
int heap[50003],pozheap[50003],cost[50003],viz[50003],csd[50003],ok;
void add(pnod &p,int j,int cost)
{
	pnod q=new nod;
	q->info=j;
	q->dist=cost;
	q->next=p;
	p=q;
}
void heapdown(int parent)
{
	int leftson,rightson;
	leftson=parent<<1;
	rightson=leftson|1;
	if(leftson>hl)
		return;
	if(leftson<hl)
		if(cost[heap[leftson]]>cost[heap[rightson]])
			leftson=rightson;
	if(cost[heap[leftson]]>cost[heap[parent]])
	{
		aux=heap[leftson];
		heap[leftson]=heap[parent];
		heap[parent]=aux;
		pozheap[heap[leftson]]=leftson;
		pozheap[heap[parent]]=parent;
		heapdown(leftson);
	}
}
void heapup(int son)
{
	int parent;
	parent=son>>1;
	if(!parent)
		return;
	if(cost[heap[parent]]>cost[heap[son]])
	{
		aux=heap[parent];
		heap[parent]=heap[son];
		heap[son]=aux;
		pozheap[heap[parent]]=parent;
		pozheap[heap[son]]=son;
		heapup(parent);
	}
}
void remove(pnod &p)
{
	pnod q,r;
	while(p!=NULL)
	{
		q=p->next;
		r=p;
		p=q;
		delete r;
	}
}
int main()
{
	freopen("distante.in","r",stdin);
	freopen("distante.out","w",stdout);
	scanf("%d\n",&t);
	for(;t;--t)
	{
		scanf("%d %d %d",&n,&m,&s);
		for(i=1;i<=n;++i)
			scanf("%d",csd[i]);
		for(i=1;i<=m;++i)
		{
			scanf("%d %d %d",&a,&b,&c);
			add(L[a],b,c);
			add(L[b],a,c);
		}
		for(i=1;i<=n;++i)
		{
			heap[i]=pozheap[i]=i;
			cost[i]=INF;
		}
		cost[s]=0;
		hl=n;
		while(hl && cost[heap[s]]<INF)
		{
			cv=heap[s];
			viz[heap[s]]=1;
			cd=cost[cv];
			heap[s]=heap[hl];
			pozheap[heap[s]]=s;
			--hl;
			heapdown(s);
			g=L[cv];
			while(g)
			{
				if(viz[g->info])
					g=g->next;
				else
				{
					if(cost[g->info]>cd+g->dist)
					{
						cost[g->info]=cd+g->dist;
						heapup(pozheap[g->info]);
					}
					g=g->next;
				}
			}
		}
		for(i=1;i<=n;++i)
		{
			if(cost[i]==INF)
				cost[i]=0;
			if(cost[i]!=csd[i])
			{
				ok=1;
				break;
			}
		}
		if(!ok)
			printf("DA\n");
		else
			printf("NU\n");
		ok=0;
		for(i=1;i<=n;++i)
			remove(L[i]);
	}
	return 0;
}