Cod sursa(job #494033)

Utilizator mihai995mihai995 mihai995 Data 20 octombrie 2010 15:49:01
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <fstream>
using namespace std;

const char r[][5]={"NU\n","DA\n"};
struct coarda{int x,y,d;} a[1<<17];
int v[1<<16],dist[1<<16],sol[1<<16],st[1<<16],poz[1<<16],m,n;

ifstream in("distante.in");
ofstream out("distante.out");

inline bool comp(int a,int b)
{
	if (dist[b]<dist[a])
	{
		int d=v[a];
		v[a]=v[b];
		v[b]=d;
		d=poz[v[a]];
		poz[v[a]]=poz[v[b]];
		poz[v[b]]=d;
		return true;
	}
	return false;
}

bool cmp(coarda a,coarda b)
{
	return a.x<b.x || a.x==b.x && a.y<b.y;
}

bool verif()
{
	for (int i=1;i<=n;i++)
		if (dist[i]!=sol[i])
			return false;
	return true;
}

inline void up(int x)
{
	if (x>1 && comp(x,x>>1))
		up(x>>1);
}

inline void down(int x)
{
	int m=x;
	if (2*x<=v[0] && dist[x]>dist[x<<1])
		m=x<<1;
	if (2*x<v[0] && dist[x]>dist[2*x+1])
		m=2*x+1;
	if (m!=x)
	{
		comp(m,x);
		down(m);
	}
}

void init()
{
	for (int i=0;i<1<<16;i++)
	{
		dist[i]=1<<30;
		poz[i]=0;
	}
}	

void set_st()
{
	int i,j;
	for (i=j=1;i<=n;i++)
	{
		for (;a[j].x<i && j<=m;j++);
		st[i]=j;
	}
	st[n+1]=m+1;
}

inline void add(int x,int y,int d)
{
	if (dist[y]>dist[x]+d)
	{
		dist[y]=dist[x]+d;
		if (poz[y])
			down(poz[y]);
		else
		{
			poz[y]=++v[0];
			v[v[0]]=y;
			up(y);
		}
	}
}
	
int main()
{
	int s,t,i;
	in>>t;
	while (t--)
	{
		init();
		in>>n>>m>>s;
		for (i=1;i<=n;i++)
			in>>sol[i];
		for (i=1;i<=m;i++)
		{
			in>>a[i].x>>a[i].y>>a[i].d;
			a[i+m].x=a[i].y;
			a[i+m].y=a[i].x;
			a[i+m].d=a[i].d;
		}
		m<<=1;
		sort(a+1,a+m+1,cmp);
		set_st();
		dist[s]=0;
		v[0]=1;
		v[1]=s;
		poz[s]=1;
		while (v[0])
		{
			s=v[1];
			for (i=st[s];i<st[s+1];i++)
				add(s,a[i].y,a[i].d);
			v[1]=v[v[0]--];
			down(1);
		}
		out<<r[verif()];
	}
	return 0;
}