Cod sursa(job #485651)

Utilizator IrnukIrina Grosu Irnuk Data 19 septembrie 2010 00:09:33
Problema Distante Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.97 kb
#include<fstream>
#include<list>
#include<vector>
#define lg (heap.size()-1)
#define NMAX 50005
using namespace std;

long T,n,m,s;
	long ok=1;
long distanta[NMAX],vizitat[NMAX];
long long dist[NMAX];
//
//struct nod
//{
//	long vf;
//	long cost;
//	nod(long nvf,long ncost)
//	{
//		vf=nvf;
//		cost=ncost;
//	}
//};

vector<list<pair<long,long> > > G;
vector<long> heap;
long pozInHeap[NMAX];

long fiuS(long vf)
{
	return 2*vf;
}

long fiuD(long vf)
{
	return 2*vf+1;
}

void swap(long poz1, long poz2)
{
	long aux;

	aux=heap[poz1];
	heap[poz1]=heap[poz2];
	heap[poz2]=aux;
	
	aux=pozInHeap[heap[poz1]];
	pozInHeap[heap[poz1]]=pozInHeap[heap[poz2]];
	pozInHeap[heap[poz2]]=aux;
}

void moveDown(long vf)
{
	long fius=fiuS(vf),fiud=fiuD(vf);
	long pozmin,ok=0;

	while(fius<=lg && ok==0)
	{
		pozmin=vf;

		if(dist[fius]<dist[vf])
			pozmin=fius;
		
		if(fiud<=lg && dist[fiud]<dist[pozmin])
			pozmin=fius;

		if(pozmin==vf)
			ok=1;
		else
		{
			swap(pozmin,vf);
			fiud=fiuD(pozmin);
			fius=fiuS(pozmin);
			vf=pozmin/2;
		}

	}

}

void moveUp(long vf)
{
	long parinte = vf/2;

	while(parinte>=1)
	{
		if(dist[parinte]>dist[vf])
			swap(parinte,vf);
		else
			parinte=-1;
		parinte/=2;
	}
}

void dijkstra()
{
	list<pair<long,long> >::iterator itr;
	pair<long,long> que;
	long el;

	dist[s]=0;
	heap.push_back(s);

	while(heap.size()>1)
	{
		el=heap[1];
		pozInHeap[heap[1]]=-1;
		pozInHeap[heap[lg]]=1;
		heap[1]=heap[lg];
		heap.pop_back();
		moveDown(1);

		for(itr=G[el].begin();itr!=G[el].end(); itr++)
		{
			que=*itr;
			if(dist[que.first]>dist[el]+que.second)
			{
				dist[que.first]=dist[el]+que.second;
				if(vizitat[que.first]==0)
				{
					heap.push_back(que.first);
					pozInHeap[que.first]=lg;
					moveUp(pozInHeap[que.first]);
					vizitat[que.first]=1;
				}
			}
		}

		if(distanta[el]==0)
		{
			if(dist[el]==LONG_MAX)
				;
			else
			{
				ok=0;
				heap.clear();
			}
		}
		else
			if(dist[el]!=distanta[el])
			{
				ok=0;
				heap.clear();
			}


	}
}

int main()
{
	fstream fin,fout;
	long contT,i,x,y,c;
	list<pair<long, long> > lista;
	G.push_back(lista);

	fin.open("distante.in",ios::in);
	fout.open("distante.out",ios::out);

	fin>>T;
	
	for(contT = 0; contT < T; contT++)
	{
		fin>>n>>m>>s;
		heap.push_back(0);
		G.push_back(lista);

		for(i=1;i<=n;i++)
		{
			fin>>distanta[i];
			G.push_back(lista);
			dist[i]=LONG_MAX;
			vizitat[i]=0;
		}

		for(i=1;i<=m;i++)
		{
			fin>>x>>y>>c;
			G[x].push_back(make_pair(y,c));
			G[y].push_back(make_pair(x,c));
		}

		dijkstra();
		for(i=1;i<=n && ok==1;i++)
		{
			if(dist[i]==LONG_MAX)
				dist[i]=0;
			if(distanta[i]!=dist[i])
				ok=0;
			dist[i]=distanta[i]=0;
		}
		if(ok==1)
			fout<<"DA\n";
		else
			fout<<"NU\n";

		heap.clear();
		//for(i=0;i<=n;i++)
		//	G.pop_back();
		G.clear();
	}


	fin.close();
	fout.close();
	return 0;
}