#include <cstdio>
#define maxn 50002
#define maxm 100002
#define inf 2<<28
FILE *in = fopen("distante.in","r"), *out = fopen("distante.out","w");
//struct muchie
//{
// int x, y, c;
//};
//
//int t, n, m, s;
//int d[maxn];
//muchie a[maxm];
//
//void go()
//{
// if ( d[s-1] != 0 )
// {
// fprintf(out, "NU\n");
// return;
// }
//
// for ( int i = 0; i < m; ++i )
// if ( d[a[i].x - 1] + a[i].c < d[a[i].y - 1] )
// {
// fprintf(out, "NU\n");
// return;
// }
// fprintf(out, "DA\n");
//
// return;
//}
//
//int main()
//{
// fscanf(in, "%d", &t);
//
// while ( t-- )
// {
// fscanf(in, "%d %d %d", &n, &m, &s);
// for ( int i = 0; i < n; ++i )
// fscanf(in, "%d", &d[i]);
//
// for ( int i = 0; i < m; ++i )
// fscanf(in, "%d %d %d", &a[i].x, &a[i].y, &a[i].c);
//
// go();
// }
//
// return 0;
//}
struct graf
{
int nod, cost;
graf *next;
};
int n, m, s;
graf *a[maxn] = {NULL};
int d[maxn]; // d[i] = distanta minima de la sursa la nodul i
int h[maxn]; // heap-ul
int dd[maxn];
void add(int x, int y, int c)
{
graf *q = new graf;
q->next = a[x];
q->nod = y;
q->cost = c;
a[x] = q;
}
//void go()
//{
// if ( d[s-1] != 0 )
// {
// fprintf(out, "NU\n");
// return;
// }
//
// for ( int i = 0; i < m; ++i )
// if ( d[a[i].x - 1] + a[i].c < d[a[i].y - 1] )
// {
// fprintf(out, "NU\n");
// return;
// }
// fprintf(out, "DA\n");
//
// return;
//}
int poz[maxn]; // poz[i] = pozitia nodului i in heap (vectorul h). -1 daca nodul i nu este in heap
int k;
void swap(int x, int y)
{
int t = h[x];
h[x] = h[y];
h[y] = t;
}
void upheap(int what)
{
int tata;
while ( what > 1 )
{
tata = what >> 1;
if ( d[ h[tata] ] > d[ h[what] ] )
swap(tata, what), poz[ h[what] ] = tata, what = tata;
else
what = 1;
}
}
void downheap(int what)
{
int f;
while ( what <= k )
{
f = what;
if ( (what<<1) <= k )
f = what << 1;
if ( f + 1 <= k )
if ( d[ h[f + 1] ] < d[ h[f] ] )
++f;
if ( d[ h[what] ] > d[ h[f] ] )
swap(what, f), what = f;
else
what = k+1;
}
}
void dijkstra_heap(int sursa)
{
for ( int i = 1; i <= n; ++i )
d[i] = inf, poz[i] = -1, h[i] = 0;
d[sursa] = 0;
poz[sursa] = 1;
k = 0;
h[++k] = sursa;
for ( int i = 2; i <= n; ++i )
{
int min = h[1];
swap(1, k);
--k;
downheap(1);
graf *q = a[min];
while ( q )
{
if ( d[q->nod] > d[min] + q->cost )
{
d[q->nod] = d[min] + q->cost;
if ( poz[q->nod] != -1 )
upheap( poz[q->nod] );
else
{
h[++k] = q->nod;
poz[ h[k] ] = k;
upheap( k );
}
}
q = q->next;
}
}
}
char tk[maxn] = {0};
void dijkstra_clasic(int sursa)
{
for ( int i = 1; i <= n; ++i )
d[i] = inf, tk[i] = 0;
d[sursa] = 0;
for ( int i = 1; i <= n; ++i )
{
int min = inf;
int poz = 1;
for ( int j = 1; j <= n; ++j )
if ( d[j] < min && !tk[j] )
min = d[j], poz = j;
tk[poz] = 1;
graf *q = a[poz];
while ( q )
{
if ( d[q->nod] > d[poz] + q->cost )
d[q->nod] = d[poz] + q->cost;
q = q->next;
}
}
}
int main()
{
int t;
fscanf(in, "%d", &t);
int x, y, c;
while ( t-- )
{
fscanf(in, "%d %d %d", &n, &m, &s);
for ( int i = 1; i <= n; ++i )
fscanf(in, "%d", &dd[i]), a[i] = NULL;
for ( int i = 0; i < m; ++i )
{
fscanf(in, "%d %d %d", &x, &y, &c);
add(x, y, c);
add(y, x, c);
}
// for ( int i = 1; i <= n; ++i )
// {
// printf("%d : ", i);
// graf *q = a[i];
// while ( q )
// {
// printf("%d ", q->nod);
// q = q->next;
// }
// printf("\n");
// }
// printf("\n\n");
dijkstra_heap(s);
int ok = 1;
for ( int i = 1; i <= n; ++i )
if ( d[i] != dd[i] )
{
fprintf(out, "NU\n");
ok = 0;
break;
}
if ( ok )
fprintf(out, "DA\n");
}
return 0;
}