Cod sursa(job #196944)

Utilizator AndreyPAndrei Poenaru AndreyP Data 30 iunie 2008 13:13:35
Problema Distante Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include<stdio.h>
#define N 50005
#define father(x) x>>1
#define left_son(x) x<<1
#define right_son(x) (x<<1)+1
#define inf 1<<30
int t,n,m,s;
struct graf
{
	int nod,cost;
	graf *next;
};
graf *a[N];
int poz[N],sol[N],d[N],k,h[N];
void adauga(int nod1,int nod2,int cost)
{
	graf *g1=new graf;
	g1->nod=nod2;
	g1->cost=cost;
	g1->next=a[nod1];
	a[nod1]=g1;
	graf *g2=new graf;
	g2->nod=nod1;
	g2->cost=cost;
	g2->next=a[nod2];
	a[nod2]=g2;
}
void citeste()
{
	int i,x,y,z;
	scanf("%d%d%d",&n,&m,&s);
	for(i=1; i<=n; i++)
	{
		scanf("%d",&sol[i]);
		a[i]=NULL;
	}
	for(i=0; i<m; i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		adauga(x,y,z);
	}
}
void swap(int &x,int &y)
{
	int aux;
	aux=x;
	x=y;
	y=aux;
}
void upheap(int y)
{
	int key=h[y];
	while((k>1)&&(d[key]<d[h[father(y)]]))
	{
		h[y]=h[father(y)];
		poz[h[y]]=y;
		y=father(y);
	}
	h[y]=key;
	poz[key]=y;
}
void downheap(int y)
{
	int son=0;
	do
	{
		son=0;
		if(left_son(y)<=k)
		{
			son=left_son(y);
			if(right_son(y)<=k)
			{
				if(d[h[right_son(y)]]<d[h[son]])
					son=right_son(y);
			}
			if(d[h[son]]>=d[h[y]])
				son=0;
		}
		if(son)
		{
			swap(h[y],h[son]);
			poz[h[y]]=y;
			poz[h[son]]=son;
			y=son;
		}
	}while(son);
}
void dijkstra_heap()
{
	int i,min;
	if(sol[s])
	{
		printf("NU\n");
		return;
	}
	graf *g;
	for(i=1; i<=n; i++)
	{
		d[i]=inf;
		poz[i]=0;
	}
	d[s]=0;
	poz[s]=1;
	h[++k]=s;
	while(k)
	{
		min=h[1];
		swap(h[1],h[k]);
		poz[h[1]]=1;
		poz[h[k]]=0;
		k--;
		downheap(1);
		g=a[min];
		while(g)
		{
			if(d[g->nod]>d[min]+g->cost)
			{
				d[g->nod]=d[min]+g->cost;
				if(poz[g->nod])
					upheap(poz[g->nod]);
				else
				{
					h[++k]=g->nod;
					poz[g->nod]=k;
					upheap(k);
				}
				if(d[g->nod]<sol[g->nod])
				{
					printf("NU\n");
					return;
				}
			}
			g=g->next;
		}
	}
	for(i=1; i<=n; i++)
		if(sol[i]!=d[i])
		{
			if(!((sol[i]==0)&&(d[i]==inf)))
			{
				printf("NU\n");
				return;
			}
		}
	printf("DA\n");
}
void rezolva()
{
	citeste();
	dijkstra_heap();
}
int main()
{
	freopen("distante.in","r",stdin);
	freopen("distante.out","w",stdout);
	int i;
	scanf("%d",&t);
	for(i=0; i<t; i++)
		rezolva();
}