Cod sursa(job #1225419)

Utilizator BLz0rDospra Cristian BLz0r Data 2 septembrie 2014 15:54:14
Problema Distante Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define inf 2000000000

FILE *f=fopen ("distante.in","r");
FILE *g=fopen ("distante.out","w");

struct nod{
	int vf,cost;
	nod *next;
}*graf[50005];

int heap[50005],dist[50005],poz[50005],init[50005],n,m,lgh;
bool ok;

void resetall (){
	ok=1;
	
	for (int i=1;i<=n;++i){
		graf[i]=NULL;
	}
}

void add (int where,int what, int cost){
	nod *q=new nod;
	q->vf=what; q->cost=cost; q->next=NULL;
	if (graf[where]==NULL){
		graf[where]=new nod;
		graf[where]->vf=where;
		graf[where]->cost=0;
		graf[where]->next=NULL;
	}
	q->next=graf[where];
	graf[where]=q;
}

inline void swapp (int i, int j){
	swap (heap[i],heap[j]);
	swap (poz[heap[i]],poz[heap[j]]);
}

inline int Lson (int nod){
	return nod<<1;
}
inline int Rson (int nod){
	return (nod<<1)+1;
}
inline int father (int nod){
	return nod>>1;
}	

void upheap (int nod){
	if (dist[heap[father(nod)]]<dist[heap[nod]]) return;
	swapp (father(nod),nod);
	upheap (father(nod));
}

void downheap (int nod){
	int st,dr;
	if (Lson(nod)>lgh) return;
	
	st=dist[heap[Lson(nod)]];
	if (Rson(nod)<=lgh) dr=dist[heap[Rson (nod)]];
	else dr=st+1;
	
	if (st<dr){
		if (dist[heap[nod]]<=st) return;
		swapp (nod,Lson(nod));
		downheap (Lson(nod));
	}
	else{
		if (dist[heap[nod]]<=dr) return;
		swapp (nod,Rson(nod));
		downheap (Rson(nod));
	}
}

void Dijkstra (int start){
	int actual;
	nod *q;
	
	for (int i=1;i<=n;++i){
		dist[i]=inf;
		heap[i]=i;
		poz[i]=i;
	}
	swapp (heap[1],heap[start]);
	dist[0]=-1; dist[start]=0;

	for (int i=1;i<=n;++i){
		actual=heap[1];
		swapp (1,lgh); lgh--;
		downheap(1);
		
		for (q=graf[actual];q!=NULL;q=q->next){
			if (dist[q->vf]>dist[actual]+q->cost){
				dist[q->vf]=dist[actual]+q->cost;
				upheap (poz[q->vf]);
			}
		}
	}
}

int main(){
	int T,a,b,c,start;
	
	fscanf (f,"%d",&T);
	
	for (;T;--T){
		resetall();
		fscanf (f,"%d%d%d",&n,&m,&start); lgh=n;
		for (int i=1;i<=n;++i) fscanf (f,"%d",&init[i]);
		for (int i=1;i<=m;++i){
			fscanf (f,"%d%d%d",&a,&b,&c);
			add (a,b,c);
			add (b,a,c);
		}
		
		if (init[start]!=0){
			fprintf (g,"NU\n");
			continue;
		}
		Dijkstra (start);
		
		for (int i=1;i<=n;++i){
			if (dist[i]!=init[i]){
				ok=0;
				fprintf (g,"NU\n");
				break;
			}
		}
		if (ok) fprintf (g,"DA\n");
	}
	
	return 0;
}