#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 内部定数
#define D_ON			1										// 汎用フラグ - ON
#define D_OFF			0										// 汎用フラグ - OFF
#define D_TOWN_MAX		200										// 最大町数
#define D_VISIT_MAX		8										// 最大訪問町数

// 内部構造体 - 町情報
typedef struct Town {
	int mi1TNo[D_TOWN_MAX];										// 隣接町 1～
	int mi1Len[D_TOWN_MAX];										// 隣接町までの距離
	int miTCnt;													// 隣接町数
	int miMin;													// 特定の町からの最短距離
} Town;

// 内部構造体 - ヒープ情報
typedef struct Heap {
	int miTNo;													// 隣接町 1～
	int miLen;													// 隣接町までの累計距離
} Heap;

// 内部変数
static Town sz1Town[D_TOWN_MAX + 5];							// 町情報
static int siTCnt;												// 町情報数
static int si1Visit[D_VISIT_MAX];								// 訪問町
static int siVCnt;												// 訪問町数
static Heap sz1Heap[D_TOWN_MAX * D_TOWN_MAX];					// ヒープ
static int siHCnt;												// ヒープ数
static int si2Min[D_VISIT_MAX + 5][D_VISIT_MAX + 5];			// 訪問町間の最短距離
static int siMin;												// 全訪問の最短距離

// 内部変数 - テスト用
#ifdef D_TEST
	static int siRes;
	static FILE *szpFpT, *szpFpA;
#endif

// 隣接町情報をセット
int
fSetTown(
	int piTNo1					// <I> 町情報１ 1～
	, int piTNo2				// <I> 町情報２ 1～
	, int piLen					// <I> 距離
)
{
	// 対象データ
	Town *lzpTown = &sz1Town[piTNo1];

	// セット
	lzpTown->mi1TNo[lzpTown->miTCnt] = piTNo2;		// 隣接町
	lzpTown->mi1Len[lzpTown->miTCnt] = piLen;		// 隣接町までの距離
	lzpTown->miTCnt++;								// 隣接町数
	
	return 0;
}

// ヒープ - 親子関係チェック
// 戻り値：[>=0]:変更した子の配列番号 [-1]:変更なし
int
fHeapChk(
	int piPNo					// <I> 親の配列番号 0～
)
{
	// 最小値
	int liMNo = piPNo;

	// 左の子と比較
	int liCNo = piPNo * 2 + 1;
	if (liCNo < siHCnt) {
		if (sz1Heap[liMNo].miLen > sz1Heap[liCNo].miLen) {
			liMNo = liCNo;
		}
	}

	// 右の子と比較
	liCNo = piPNo * 2 + 2;
	if (liCNo < siHCnt) {
		if (sz1Heap[liMNo].miLen > sz1Heap[liCNo].miLen) {
			liMNo = liCNo;
		}
	}

	// 自分が最小値であるかチェック
	if (piPNo == liMNo) {
		return -1;
	}

	// 値の交換
	Heap lzWork;
	memcpy(&lzWork, &sz1Heap[liMNo], sizeof(Heap));
	memcpy(&sz1Heap[liMNo], &sz1Heap[piPNo], sizeof(Heap));
	memcpy(&sz1Heap[piPNo], &lzWork, sizeof(Heap));

	return liMNo;
}

// ヒープ - キュー追加
int
fHeapEnqueue(
	int piTNo					// <I> 隣接町 1～
	, int piLen					// <I> 隣接町までの累計距離
)
{
	int liRet;

	// 末尾に追加
	sz1Heap[siHCnt].miTNo = piTNo;
	sz1Heap[siHCnt].miLen = piLen;
	siHCnt++;

	// 親子関係チェック
	int liNo = siHCnt - 1;
	while (1) {

		// 親の配列番号
		liNo = (liNo - 1) / 2;

		// 親子関係チェック
		liRet = fHeapChk(liNo);
		if (liRet < 0) {
			break;
		}
	}

	return 0;
}

// ヒープ - キュー取得
int
fHeapDequeue(
	Heap *pzpRet				// <O> 取得先
)
{
	// データ数
	if (siHCnt < 1) {
		return -1;
	}

	// 取得
	memcpy(pzpRet, &sz1Heap[0], sizeof(Heap));
	siHCnt--;

	// データ数
	if (siHCnt < 1) {
		return 0;
	}

	// 末尾を先頭へ
	memcpy(&sz1Heap[0], &sz1Heap[siHCnt], sizeof(Heap));

	// 親子関係チェック
	int liNo = 0;
	while (liNo >= 0) {
		liNo = fHeapChk(liNo);
	}

	return 0;
}

// 特定の町からの最短距離をセット
int
fSetTownMin(
)
{
	int i, liRet;

	while (1) {

		// キュー取得
		Heap lzHeap;
		liRet = fHeapDequeue(&lzHeap);
		if (liRet != 0) {
			break;
		}

		// 対象データ
		Town *lzpTown = &sz1Town[lzHeap.miTNo];

		// セット済みかチェック
		if (lzpTown->miMin >= 0) {
			continue;
		}

		// セット
		lzpTown->miMin = lzHeap.miLen;

		// ヒープ追加
		for (i = 0; i < lzpTown->miTCnt; i++) {
			fHeapEnqueue(lzpTown->mi1TNo[i], lzpTown->miMin + lzpTown->mi1Len[i]);
		}
	}

	return 0;
}

// 訪問町間の最短距離をセット
int
fSetVisit(
	int piVNo					// <I> 訪問町 0～
)
{
	int i;

	// 特定の町からの最短距離を初期化
	for (i = 1; i <= siTCnt; i++) {
		sz1Town[i].miMin = -1;
	}

	// 特定の町からの最短距離をセット
	fHeapEnqueue(si1Visit[piVNo], 0);		// キュー追加
	fSetTownMin();

	// 訪問町間の最短距離をセット
	for (i = 0; i < siVCnt; i++) {
		if (i != piVNo) {
			si2Min[piVNo][i] = sz1Town[si1Visit[i]].miMin;
		}
	}

	return 0;
}

// 全訪問の最短距離をセット
int
fSetMin(
	int piVNo					// <I> 現在位置
	, int *pipVNo				// <I> 訪問済町
	, int piVCnt				// <I> 訪問済町数
	, int piLen					// <I> 距離
)
{
	int i;

	// 訪問済チェック
	if (pipVNo[piVNo] != D_OFF) {
		return 0;
	}

	// 訪問完了
	if (piVCnt == siVCnt - 1) {

		// 全訪問の最短距離更新
		if (siMin > piLen) {
			siMin = piLen;
		}

		return 0;
	}

	// 訪問
	pipVNo[piVNo] = D_ON;

	// 次の町へ
	for (i = 0; i < siVCnt; i++) {
		fSetMin(i, pipVNo, piVCnt + 1, piLen + si2Min[piVNo][i]);
	}

	// 訪問解除
	pipVNo[piVNo] = D_OFF;

	return 0;
}

// 実行メイン
int
fMain(
	int piTNo					// <I> テスト番号 1～
)
{
	int i;
	char lc1Buf[1024], lc1Out[1024];

	// データ初期化
	memset(sz1Town, 0, sizeof(sz1Town));						// 町情報
	siHCnt = 0;													// ヒープ数
	siMin = INT_MAX;											// 全訪問の最短距離

	// テストファイルオープン
#ifdef D_TEST
	sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
	szpFpT = fopen(lc1Buf, "r");
	sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
	szpFpA = fopen(lc1Buf, "r");
	siRes = 0;
#endif

	// 町数・道路数・訪問町数取得
	int liRCnt;
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
	fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif
	sscanf(lc1Buf, "%d%d%d", &siTCnt, &liRCnt, &siVCnt);

	// 訪問町取得
	for (i = 0; i < siVCnt; i++) {
#ifdef D_TEST
		fscanf(szpFpT, "%d", &si1Visit[i]);
#else
		fscanf(stdin, "%d", &si1Visit[i]);
#endif
	}
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
	fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif

	// 道路取得
	for (i = 0; i < liRCnt; i++) {
		int liTNo1, liTNo2, liLen;
#ifdef D_TEST
		fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
		fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif
		sscanf(lc1Buf, "%d%d%d", &liTNo1, &liTNo2, &liLen);

		// 隣接町情報をセット
		fSetTown(liTNo1, liTNo2, liLen);
		fSetTown(liTNo2, liTNo1, liLen);
	}

	// 訪問町間の最短距離をセット
	for (i = 0; i < siVCnt; i++) {
		fSetVisit(i);
	}

	// 全訪問の最短距離をセット
	int li1VNo[D_VISIT_MAX];
	memset(li1VNo, D_OFF, sizeof(li1VNo));
	for (i = 0; i < siVCnt; i++) {
		fSetMin(i, li1VNo, 0, 0);
	}

	// 結果セット
	sprintf(lc1Out, "%d\n", siMin);

	// 結果表示
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
	if (strcmp(lc1Buf, lc1Out)) {
		siRes = -1;
	}
#else
	printf("%s", lc1Out);
#endif

	// テストファイルクローズ
#ifdef D_TEST
	fclose(szpFpT);
	fclose(szpFpA);
#endif

	// テスト結果
#ifdef D_TEST
	if (siRes == 0) {
		printf("OK %d\n", piTNo);
	}
	else {
		printf("NG %d\n", piTNo);
	}
#endif

	return 0;
}

int
main()
{

#ifdef D_TEST
	int i;
	for (i = D_TEST_SNO; i <= D_TEST_ENO; i++) {
		fMain(i);
	}
#else
	fMain(0);
#endif

	return 0;
}



Measured memory_bytes: 768