using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("8 10 4");
WillReturn.Add("0");
WillReturn.Add("1");
WillReturn.Add("1");
WillReturn.Add("2");
WillReturn.Add("1");
WillReturn.Add("1");
WillReturn.Add("2");
WillReturn.Add("0");
WillReturn.Add("1 2 1");
WillReturn.Add("1 3 1");
WillReturn.Add("2 3 3");
WillReturn.Add("2 4 5");
WillReturn.Add("3 4 1");
WillReturn.Add("4 5 1");
WillReturn.Add("5 6 1");
WillReturn.Add("5 8 1");
WillReturn.Add("1 7 2");
WillReturn.Add("7 8 2");
//9
}
else if (InputPattern == "Input2") {
WillReturn.Add("15 25 4");
WillReturn.Add("0");
WillReturn.Add("1");
WillReturn.Add("1");
WillReturn.Add("0");
WillReturn.Add("2");
WillReturn.Add("1");
WillReturn.Add("0");
WillReturn.Add("1");
WillReturn.Add("1");
WillReturn.Add("2");
WillReturn.Add("0");
WillReturn.Add("0");
WillReturn.Add("1");
WillReturn.Add("0");
WillReturn.Add("1");
WillReturn.Add("8 11 1");
WillReturn.Add("7 10 1");
WillReturn.Add("12 14 1");
WillReturn.Add("3 8 1");
WillReturn.Add("1 5 1");
WillReturn.Add("3 9 1");
WillReturn.Add("3 8 1");
WillReturn.Add("1 5 1");
WillReturn.Add("6 15 1");
WillReturn.Add("11 12 1");
WillReturn.Add("2 14 1");
WillReturn.Add("7 10 1");
WillReturn.Add("11 12 1");
WillReturn.Add("5 13 1");
WillReturn.Add("2 8 1");
WillReturn.Add("1 4 1");
WillReturn.Add("2 11 1");
WillReturn.Add("5 6 1");
WillReturn.Add("1 13 1");
WillReturn.Add("6 12 1");
WillReturn.Add("5 10 1");
WillReturn.Add("9 13 1");
WillReturn.Add("4 10 1");
WillReturn.Add("3 12 1");
WillReturn.Add("7 13 1");
//6
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] GetSplitArr(string pStr)
{
return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => long.Parse(pX)).ToArray();
}
struct EdgeInfoDef
{
internal long ToNode;
internal long Cost;
}
static Dictionary<long, List<EdgeInfoDef>> mEdgeInfoListDict = new Dictionary<long, List<EdgeInfoDef>>();
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = (pStr) => wkArr = GetSplitArr(pStr);
SplitAct(InputList[0]);
long N = wkArr[0];
long X = wkArr[2];
// 温度[ノード]
var OndoDict = new Dictionary<long, long>();
for (long I = 1; I <= N; I++) {
OndoDict[I] = long.Parse(InputList[(int)I]);
}
foreach (string EachStr in InputList.Skip(1 + (int)N)) {
SplitAct(EachStr);
long A = wkArr[0];
long B = wkArr[1];
long C = wkArr[2];
Action<long, long, long> AddEdgeAct = (pFromNode, pToNode, pCost) =>
{
if (mEdgeInfoListDict.ContainsKey(pFromNode) == false) {
mEdgeInfoListDict[pFromNode] = new List<EdgeInfoDef>();
}
EdgeInfoDef WillAdd;
WillAdd.ToNode = pToNode;
WillAdd.Cost = pCost;
mEdgeInfoListDict[pFromNode].Add(WillAdd);
};
AddEdgeAct(A, B, C);
AddEdgeAct(B, A, C);
}
var InsPQueue = new PQueue();
PQueue.PQueueJyoutaiDef WillEnqueue;
WillEnqueue.CurrNode = 1;
WillEnqueue.CurrJyoutai = 0;
WillEnqueue.RestTime = X;
WillEnqueue.Val = 0;
InsPQueue.Enqueue(WillEnqueue);
var VisitedSet = new HashSet<string>();
while (InsPQueue.Count() > 0) {
PQueue.PQueueJyoutaiDef Dequeued = InsPQueue.Dequeue();
// クリア判定
if (Dequeued.CurrNode == N) {
Console.WriteLine(Dequeued.Val);
return;
}
// 枝切り
string Hash = string.Format("{0},{1},{2}",
Dequeued.CurrNode, Dequeued.CurrJyoutai, Dequeued.RestTime);
if (VisitedSet.Add(Hash) == false) {
continue;
}
foreach (EdgeInfoDef EachEdgeInfo in mEdgeInfoListDict[Dequeued.CurrNode]) {
long NewNode = EachEdgeInfo.ToNode;
WillEnqueue.CurrNode = NewNode;
WillEnqueue.CurrJyoutai = Dequeued.CurrJyoutai;
WillEnqueue.RestTime = Dequeued.RestTime - EachEdgeInfo.Cost;
WillEnqueue.RestTime = Math.Max(0, WillEnqueue.RestTime);
if (WillEnqueue.RestTime == 0) {
WillEnqueue.CurrJyoutai = 1;
}
if (OndoDict[NewNode] == 0 && WillEnqueue.CurrJyoutai == 2) {
continue;
}
if (OndoDict[NewNode] == 2 && WillEnqueue.CurrJyoutai == 0) {
continue;
}
if (OndoDict[NewNode] == 0) {
WillEnqueue.CurrJyoutai = 0;
WillEnqueue.RestTime = X;
}
if (OndoDict[NewNode] == 2) {
WillEnqueue.CurrJyoutai = 2;
WillEnqueue.RestTime = X;
}
WillEnqueue.Val = Dequeued.Val + EachEdgeInfo.Cost;
InsPQueue.Enqueue(WillEnqueue);
}
}
}
}
#region PQueue
// 優先度付きキュー (根のValが最小)
internal class PQueue
{
internal struct PQueueJyoutaiDef
{
internal long CurrNode;
internal long CurrJyoutai;
internal long RestTime;
internal long Val;
}
private Dictionary<int, PQueueJyoutaiDef> mHeapDict = new Dictionary<int, PQueueJyoutaiDef>();
internal bool IsEmpty()
{
return mHeapDict.Count == 0;
}
internal long Count()
{
return mHeapDict.Count;
}
internal long Peek()
{
return mHeapDict[1].Val;
}
// エンキュー処理
internal void Enqueue(PQueueJyoutaiDef pAddJyoutai)
{
int CurrNode = 1 + mHeapDict.Count;
mHeapDict[CurrNode] = pAddJyoutai;
while (1 < CurrNode && mHeapDict[CurrNode / 2].Val > mHeapDict[CurrNode].Val) {
PQueueJyoutaiDef Swap = mHeapDict[CurrNode];
mHeapDict[CurrNode] = mHeapDict[CurrNode / 2];
mHeapDict[CurrNode / 2] = Swap;
CurrNode /= 2;
}
}
// デキュー処理
internal PQueueJyoutaiDef Dequeue()
{
PQueueJyoutaiDef TopNode = mHeapDict[1];
int LastNode = mHeapDict.Count;
mHeapDict[1] = mHeapDict[LastNode];
mHeapDict.Remove(LastNode);
MinHeapify(1);
return TopNode;
}
// 根ノードを指定し、根から葉へヒープ構築
private void MinHeapify(int pRootNode)
{
if (mHeapDict.Count <= 1) {
return;
}
int Left = pRootNode * 2;
int Right = pRootNode * 2 + 1;
// 左の子、自分、右の子で値が最小のノードを選ぶ
long Smallest = mHeapDict[pRootNode].Val;
int SmallestNode = pRootNode;
if (mHeapDict.ContainsKey(Left) && mHeapDict[Left].Val < Smallest) {
Smallest = mHeapDict[Left].Val;
SmallestNode = Left;
}
if (mHeapDict.ContainsKey(Right) && mHeapDict[Right].Val < Smallest) {
Smallest = mHeapDict[Right].Val;
SmallestNode = Right;
}
// 子ノードのほうが小さい場合
if (SmallestNode != pRootNode) {
PQueueJyoutaiDef Swap = mHeapDict[SmallestNode];
mHeapDict[SmallestNode] = mHeapDict[pRootNode];
mHeapDict[pRootNode] = Swap;
// 再帰的に呼び出し
MinHeapify(SmallestNode);
}
}
}
#endregion