Cod sursa(job #504816)

Utilizator brainwashed20Alexandru Gherghe brainwashed20 Data 28 noiembrie 2010 20:07:58
Problema Distante Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.73 kb
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>

#define Nmax 50001
#define INF 0x3f3f3f3f

using namespace std;

int H[Nmax], poz[Nmax], Dinit[Nmax], D[Nmax], N, M, S, L;

vector < pair <int, int> > G[Nmax];

void Heap_Up(int k) {
	while(k>1 && D[H[k]]<D[H[k/2]]) {
		swap(poz[H[k]],poz[H[k/2]]);
		swap(H[k],H[k/2]);
		k/=2;
	}
}

void insert(int val) {
	H[++L]=val;
	poz[H[L]]=L;
	Heap_Up(L);
}

void Heap_Down(int k) {
	int son=k;
	if(2*k<=L && D[H[2*k]]<D[H[son]])
		son=2*k;
	if(2*k+1<=L && D[H[2*k+1]]<D[H[son]])
		son=2*k+1;
	if(son!=k) {
		swap(H[k],H[son]);
		swap(poz[H[k]],poz[H[son]]);
		Heap_Down(son);
	}
}

void erase(int k) {
	H[k]=H[L];
	poz[H[k]]=k;
	L--;
	Heap_Down(k);
}

void dijkstra() {
	int i, min, cost, nod;
	vector < pair <int, int> > :: iterator it;
	
	for(i=1; i<=N; i++) 
		H[i]=0, D[i]=INF, poz[i]=-1;
	L=0; insert(S); D[S]=0;
	while(L) {
		min=H[1];
		erase(1);
		for(it=G[min].begin(); it!=G[min].end(); it++) {
			nod=it->first;
			cost=it->second;
			if(D[nod]>D[min]+cost) {
				D[nod]=D[min]+cost;
				if(poz[nod]!=-1) 
					Heap_Up(poz[nod]);
				else
					insert(nod);
			}
		}
	}
}

int verif() {
	int i;
	for(i=1; i<=N; i++)
		if(D[i]!=Dinit[i])
			return 0;
	return 1;
}

int main() {
	freopen("distante.in","r",stdin);
	freopen("distante.out","w",stdout);
	
	int T, i, j, c;
	
	scanf("%d",&T);
	while(T--) {
		scanf("%d %d %d",&N,&M,&S);
		for(i=1; i<=N; i++)	{
			scanf("%d",&Dinit[i]);
			G[i].clear();
		}
		while(M--) {
			scanf("%d %d %d",&i,&j,&c);
			G[i].push_back(make_pair(j,c));
			G[j].push_back(make_pair(i,c));
		}
		dijkstra();
		printf("%s\n",verif()==1 ? "DA" : "NU");
	}
	
	return 0;
}