#include <stdio.h>
#define INF 10001
#define MaxN 100001
int N, nheap, M, S;
int heap[MaxN], v[MaxN]; // heap[i] - retine POZITIA minimului din sirul v
int pos[MaxN]; // pozitia lui v[i] in heap;
struct NOD {
int vf, cost;
NOD* next;
};
typedef NOD* PNOD;
PNOD L[MaxN];
int dist[MaxN], sel[MaxN];
int pdist[MaxN];
int extrage_min();
void move_up(int poz);
void move_down(int poz);
void modifica(int poz);
void insert_heap(int poz);
void dijkstra(int, int);
void Add(int i, int j, int c)
{
PNOD p = new NOD;
p->vf = j;
p->cost = c;
p->next = L[i];
L[i] = p;
}
int main()
{
int i, j, vf1, vf2, c, T;
FILE *fin = fopen("distante.in", "rt");
FILE *fout = fopen("distante.out", "wt");
fscanf(fin, "%d", &T);
for (;T;T--)
{
fscanf(fin, "%d %d %d", &N, &M, &S);
for (i = 1; i <= N; i++) fscanf(fin, "%d", &pdist[i]);
for (i = 1; i <= N; i++) L[i] = NULL;
for (i = 1; i <= M; i++)
{
fscanf(fin, "%d %d %d", &vf1, &vf2, &c);
Add(vf1, vf2, c);
Add(vf2, vf1, c);
}
dijkstra(S, N);
int ok = 1;
for (i = 1; i <= N; i++)
if (pdist[i] != dist[i]) ok = 0;
//for (i = 1; i <= N; i++) fprintf(fout, "%d ", dist[i]);
if (ok) fprintf(fout, "DA\n");
else fprintf(fout, "NU\n");
}
fclose(fin);
fclose(fout);
return 0;
}
void insert_heap(int poz)
{
pos[poz] = ++nheap;
heap[nheap] = poz;
move_up(nheap);
}
void move_up(int poz)
{
int pnod = heap[poz], fiu = poz, tata = poz / 2;
while( tata != 0 && v[pnod] < v[heap[tata]])
{
pos[heap[tata]] = pos[heap[fiu]];
heap[fiu] = heap[tata];
fiu = tata;
tata /= 2;
}
heap[fiu] = pnod;
pos[pnod] = fiu;
}
int extrage_min()
{
int minim = heap[1];
heap[1] = heap[nheap]; pos[1] = pos[nheap];
nheap--;
move_down(1);
return minim;
}
void move_down(int poz) // poz = pozitia in sirul heap;
{
int tata = poz, fiu = poz * 2, pnod = heap[poz];
while ( fiu <= nheap && (v[pnod] > v[fiu] && v[pnod] > v[fiu+1]) )
{
if (v[heap[fiu]] > v[heap[fiu+1]]) fiu++;
heap[tata] = heap[fiu];
pos[tata] = pos[fiu];
tata = fiu;
fiu *= 2;
}
heap[tata] = pnod;
pos[pnod] = tata;
}
void dijkstra(int sursa, int dest)
{
int i, j, pas, k;
for (i = 1; i <= N; i++)
{
if (i == sursa) continue;
dist[i] = INF, sel[i] = 0;
insert_heap(i);
}
for (PNOD p = L[sursa]; p; p=p->next)
{
dist[p->vf] = p->cost;
move_up(p->vf);
}
sel[sursa] = 1;
dist[sursa] = 0;
for (pas = 1; pas < N; pas++)
{
k = extrage_min();
sel[k] = 1;
for (PNOD p = L[k]; p; p=p->next)
if (dist[p->vf] > dist[k] + p->cost)
{
dist[p->vf] = dist[k] + p->cost;
if (!pos[p->vf]) insert_heap(p->vf);
else move_up(pos[p->vf]);
}
}
}