#include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <set> #include <vector> #include<cmath> #include<algorithm> #include<stdlib.h> #define N 300050 #define inf 100000000 #define Mid(x,y) ((x+y)>>1) #define L(id) tree[id].ch[0] #define R(id) tree[id].ch[1] #define Father(id) tree[id].fa #define Size(id) tree[id].size #define Val(id) tree[id].val using namespace std; struct Edge{ int from, to, dis, nex; }edge[200050+N*2]; int head[N], edgenum; void add(int u, int v, int d){ Edge E={u,v,d,head[u]}; edge[edgenum] = E; head[u] = edgenum++; } int dis[N]; int n, m, c; struct node{ int pos, dis; bool operator<(const node&a)const{ return a.dis < dis; } node(int a=0,int b=0):pos(a),dis(b){} }; int spfa(int s, int t){ n*=3; n+=10; for(int i = 1; i <= n; i++)dis[i] = inf; dis[s] = 0; priority_queue<node>q; q.push(node(s,0)); while(!q.empty()){ node G = q.top(); q.pop(); if(G.pos == t)return G.dis; for(int i = head[G.pos]; ~i; i = edge[i].nex){ int v = edge[i].to; if(dis[v] > dis[G.pos]+edge[i].dis){ dis[v] = dis[G.pos]+edge[i].dis; q.push(node(v,dis[v])); } } } return -1; } void init(){memset(head, -1, sizeof head); edgenum = 0;} int main(){ int que, u, v, i, j, T, Cas = 1; scanf("%d",&T); while(T--){ scanf("%d %d %d",&n,&m,&c); init(); for(i = 1; i <= n; i++){ scanf("%d",&u); add(i, n + 2*u - 1, 0); add(n + 2*u, i, 0); } for(i = 1; i < n; i++) add(n + 2*i-1, n + 2*(i+1), c), add(n + 2*(i+1)-1, n+2*i, c); while(m--){ scanf("%d %d %d",&u,&v,&c); add(u,v,c);add(v,u,c); } printf("Case #%d: %d\n", Cas++, spfa(1,n)); } return 0; }