/// Punncte = 100, TIME = 0.3
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define nMax 2002
using namespace std;
const int inf = 0x3f3f3f3f;
struct Nod
{
int varf;
int cod;
int cost;
Nod(int vf = 0, int cd = 0, int c = 0)
{
varf = vf;
cod = cd;
cost = c;
}
};
queue < Nod > q;
int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], p[16], p2[17];
vector < pair< int,int > > v[nMax];
int c[17], uz[17], cost[16][1<<17];
int k, n, m, K, ax, cx;
int optim = inf, best;
void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t, int cd);
void Find();
int main()
{
freopen("ubuntzei.in", "rt", stdin);
freopen("ubuntzei.out", "wt", stdout);
ReadData();
solve();
Find();
PrintSol();
fclose(stdin);
fclose(stdout);
return 0;
}
void PrintSol()
{
int mask = (1 << K) - 1;
if (K == 0) optim = dp[0][n];
for (int i = 1; i <= K; ++i)
if (cost[i][mask] + dp[i][n] < optim)
optim = cost[i][mask] + dp[i][n];
printf("%d\n", optim);
}
void Find()
{
memset(cost, inf, sizeof(cost));
int i, x, cx, cd, dx, rx, cs;
cost[0][0] = 0;
for (q.push(Nod(0, 0, 0)); !q.empty(); q.pop())
{
x = q.front().varf;
cd = q.front().cod;
cs = q.front().cost;
dx = cost[x][cd];
if (cs > dx) continue;
//printf("%d %d\n", x, cd);
for (i = 1; i <= K; ++i)
if (cost[poz[c[i]]][cx = cd | p2[i]] > (rx = dx + dp[x][c[i]]))
{
cost[poz[c[i]]][cx] = rx;
q.push(Nod(poz[c[i]], cx, rx));
}
}
}
void combTop(int dp[nMax], int c) {
int f = c>>1;
while(f && dp[h[f]] > dp[h[c]]) {
swap(h[f], h[c]);
swap(ph[h[f]], ph[h[c]]);
c = f, f >>= 1;
}
}
void combDown(int dp[nMax], int f) {
int c = f<<1;
while(c <= k) {
if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
if(dp[h[c]] < dp[h[f]]) {
swap(h[c], h[f]);
swap(ph[h[c]], ph[h[f]]);
f = c, c <<= 1;
}
else return;
}
}
void push(int dp[nMax], int x) {
//printf("push(%d)\n", x);
h[++k] = x, ph[x] = k;
combTop(dp, k);
}
int pop(int dp[nMax]) {
int x = h[1];
//printf("pop(%d)\n", x);
h[1] = h[k--];
if(k) ph[h[1]] = 1, combDown(dp, 1);
return x;
}
void solve()
{
for (int i = 0; i <= K; ++i) dijkstra(dp[i],c[i]);
p2[1] = 1;
for (int i = 2; i < 17; ++i) p2[i] = p2[i-1] << 1;
}
void dijkstra(int dp[nMax], int x) {
//printf("dijkstra(%d)\n", x);
for(int i = 1; i <= n; ++i)
dp[i] = inf, ph[i] = 0;
dp[x] = 0; push(dp, x);
while(k) {
x = pop(dp);
//printf("%d %d\n", k, x);
/// asa e mai rapid
unsigned end = v[x].size();
for(unsigned i = 0; i < end; ++i)
if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
dp[v[x][i].first] = dp[x] + v[x][i].second;
if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
else push(dp, v[x][i].first);
}
}
}
void ReadData()
{
scanf("%d%d", &n, &m);
scanf("%d", &K);
int i, x, y, z;
c[0] = 1;
for (i = 1; i <= K; ++i)
{
scanf("%d", &c[i]);
poz[c[i]] = i;
}
for (i = 0; i < m; ++i)
{
scanf("%d%d%d", &x, &y, &z);
v[x].push_back(make_pair(y,z));
v[y].push_back(make_pair(x,z));
}
}
/*
/// Punncte = 75, TIME = tle (0.15)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define nMax 2002
using namespace std;
const int inf = 0x3f3f3f3f;
struct Nod
{
int varf;
int cod;
Nod(int vf = 0, int cd = 0)
{
varf = vf;
cod = cd;
}
};
queue < Nod > q;
int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], p[16], p2[17];
vector < pair< int,int > > v[nMax];
int c[17], uz[17], cost[16][1<<17];
int k, n, m, K, ax, cx;
int optim = inf, best;
void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t, int cd);
void Find();
int main()
{
freopen("ubuntzei.in", "rt", stdin);
freopen("ubuntzei.out", "wt", stdout);
ReadData();
solve();
Find();
PrintSol();
fclose(stdin);
fclose(stdout);
return 0;
}
void PrintSol()
{
int mask = (1 << K) - 1;
if (K == 0) optim = dp[0][n];
for (int i = 1; i <= K; ++i)
if (cost[i][mask] + dp[i][n] < optim)
optim = cost[i][mask] + dp[i][n];
printf("%d\n", optim);
}
void Find()
{
memset(cost, inf, sizeof(cost));
int i, x, cx, cd, dx, rx;
cost[0][0] = 0;
for (q.push(Nod(0, 0)); !q.empty(); q.pop())
{
x = q.front().varf;
cd = q.front().cod;
dx = cost[x][cd];
//printf("%d %d\n", x, cd);
for (i = 1; i <= K; ++i)
if (cost[poz[c[i]]][cx = cd | p2[i]] > (rx = dx + dp[x][c[i]]))
{
cost[poz[c[i]]][cx] = rx;
q.push(Nod(poz[c[i]], cx));
}
}
}
void combTop(int dp[nMax], int c) {
int f = c>>1;
while(f && dp[h[f]] > dp[h[c]]) {
swap(h[f], h[c]);
swap(ph[h[f]], ph[h[c]]);
c = f, f >>= 1;
}
}
void combDown(int dp[nMax], int f) {
int c = f<<1;
while(c <= k) {
if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
if(dp[h[c]] < dp[h[f]]) {
swap(h[c], h[f]);
swap(ph[h[c]], ph[h[f]]);
f = c, c <<= 1;
}
else return;
}
}
void push(int dp[nMax], int x) {
//printf("push(%d)\n", x);
h[++k] = x, ph[x] = k;
combTop(dp, k);
}
int pop(int dp[nMax]) {
int x = h[1];
//printf("pop(%d)\n", x);
h[1] = h[k--];
if(k) ph[h[1]] = 1, combDown(dp, 1);
return x;
}
void solve()
{
for (int i = 0; i <= K; ++i) dijkstra(dp[i],c[i]);
p2[1] = 1;
for (int i = 2; i < 17; ++i) p2[i] = p2[i-1] << 1;
}
void dijkstra(int dp[nMax], int x) {
//printf("dijkstra(%d)\n", x);
for(int i = 1; i <= n; ++i)
dp[i] = inf, ph[i] = 0;
dp[x] = 0; push(dp, x);
while(k) {
x = pop(dp);
//printf("%d %d\n", k, x);
/// asa e mai rapid
unsigned end = v[x].size();
for(unsigned i = 0; i < end; ++i)
if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
dp[v[x][i].first] = dp[x] + v[x][i].second;
if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
else push(dp, v[x][i].first);
}
}
}
void ReadData()
{
scanf("%d%d", &n, &m);
scanf("%d", &K);
int i, x, y, z;
c[0] = 1;
for (i = 1; i <= K; ++i)
{
scanf("%d", &c[i]);
poz[c[i]] = i;
}
for (i = 0; i < m; ++i)
{
scanf("%d%d%d", &x, &y, &z);
v[x].push_back(make_pair(y,z));
v[y].push_back(make_pair(x,z));
}
}
*/
/*
/// Punncte = 75, TIME = tle (0.39)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define nMax 2002
using namespace std;
const int inf = 0x3f3f3f3f;
int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], p[16], p2[17];
vector < pair< int,int > > v[nMax];
int c[17], uz[17], cost[16][1<<17];
int k, n, m, K, ax, cx;
int optim = inf, best;
void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t, int cd);
int main()
{
freopen("15-ubuntzei.in", "rt", stdin);
//freopen("ubuntzei.out", "wt", stdout);
ReadData();
solve();
GenPerm(1, 0);
PrintSol();
fclose(stdin);
fclose(stdout);
return 0;
}
void PrintSol()
{
printf("%d\n", optim);
}
void GenPerm(int t, int cd)
{
if (t > K)
{
if (best+dp[p[K]][n] < optim) optim = best+dp[p[K]][n];
}
else
for (int i = 1; i <= K; ++i)
if (!uz[i] and best+dp[p[t-1]][c[i]] < cost[ax = poz[c[i]]][cx = cd | p2[ax]])
{
uz[i] = 1;
p[t] = ax;
best += dp[p[t-1]][c[i]];
cost[p[t]][cx] = best;
GenPerm(t+1, cx);
uz[i] = 0;
best -= dp[p[t-1]][c[i]];
}
}
void combTop(int dp[nMax], int c) {
int f = c>>1;
while(f && dp[h[f]] > dp[h[c]]) {
swap(h[f], h[c]);
swap(ph[h[f]], ph[h[c]]);
c = f, f >>= 1;
}
}
void combDown(int dp[nMax], int f) {
int c = f<<1;
while(c <= k) {
if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
if(dp[h[c]] < dp[h[f]]) {
swap(h[c], h[f]);
swap(ph[h[c]], ph[h[f]]);
f = c, c <<= 1;
}
else return;
}
}
void push(int dp[nMax], int x) {
//printf("push(%d)\n", x);
h[++k] = x, ph[x] = k;
combTop(dp, k);
}
int pop(int dp[nMax]) {
int x = h[1];
//printf("pop(%d)\n", x);
h[1] = h[k--];
if(k) ph[h[1]] = 1, combDown(dp, 1);
return x;
}
void solve()
{
for (int i = 0; i <= K; ++i) dijkstra(dp[i],c[i]);
p2[1] = 1;
for (int i = 2; i < 17; ++i) p2[i] = p2[i-1] << 1;
}
void dijkstra(int dp[nMax], int x) {
//printf("dijkstra(%d)\n", x);
for(int i = 1; i <= n; ++i)
dp[i] = inf, ph[i] = 0;
dp[x] = 0; push(dp, x);
while(k) {
x = pop(dp);
//printf("%d %d\n", k, x);
/// asa e mai rapid
unsigned end = v[x].size();
for(unsigned i = 0; i < end; ++i)
if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
dp[v[x][i].first] = dp[x] + v[x][i].second;
if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
else push(dp, v[x][i].first);
}
}
}
void ReadData()
{
scanf("%d%d", &n, &m);
scanf("%d", &K);
int i, x, y, z;
c[0] = 1;
for (i = 1; i <= K; ++i)
{
scanf("%d", &c[i]);
poz[c[i]] = i;
}
for (i = 0; i < m; ++i)
{
scanf("%d%d%d", &x, &y, &z);
v[x].push_back(make_pair(y,z));
v[y].push_back(make_pair(x,z));
}
memset(cost, inf, sizeof(cost));
}
*/
/*
/// Punncte = 50, TIME = tle
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define nMax 2002
using namespace std;
const int inf = 0x3f3f3f3f;
int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], uz[nMax], p[16];
vector < pair< int,int > > v[nMax];
int c[16], cost[16][1<<17];
int k, n, m, K;
int optim = inf, best;
void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t);
int main()
{
freopen("14-ubuntzei.in", "rt", stdin);
//freopen("ubuntzei.out", "wt", stdout);
ReadData();
solve();
GenPerm( 1 );
PrintSol();
fclose(stdin);
fclose(stdout);
return 0;
}
void PrintSol()
{
printf("%d\n", optim);
}
void GenPerm(int t)
{
if (t > K)
{
if (best+dp[poz[p[K]]][n] < optim) optim = best+dp[poz[p[K]]][n];
}
else
for (int i = 1; i <= K; ++i)
if (!uz[c[i]] and best+dp[poz[p[t-1]]][c[i]] < optim)
{
uz[c[i]] = 1;
p[t] = c[i];
best += dp[poz[p[t-1]]][c[i]];
///printf("%d\n", best);
GenPerm(t+1);
uz[c[i]] = 0;
best -= dp[poz[p[t-1]]][c[i]];
}
}
void combTop(int dp[nMax], int c) {
int f = c>>1;
while(f && dp[h[f]] > dp[h[c]]) {
swap(h[f], h[c]);
swap(ph[h[f]], ph[h[c]]);
c = f, f >>= 1;
}
}
void combDown(int dp[nMax], int f) {
int c = f<<1;
while(c <= k) {
if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
if(dp[h[c]] < dp[h[f]]) {
swap(h[c], h[f]);
swap(ph[h[c]], ph[h[f]]);
f = c, c <<= 1;
}
else return;
}
}
void push(int dp[nMax], int x) {
//printf("push(%d)\n", x);
h[++k] = x, ph[x] = k;
combTop(dp, k);
}
int pop(int dp[nMax]) {
int x = h[1];
//printf("pop(%d)\n", x);
h[1] = h[k--];
if(k) ph[h[1]] = 1, combDown(dp, 1);
return x;
}
void solve()
{
int i;
for (i = 0; i <= K; ++i)
{
dijkstra(dp[i],c[i]);
}
}
void dijkstra(int dp[nMax], int x) {
//printf("dijkstra(%d)\n", x);
for(int i = 1; i <= n; ++i)
dp[i] = inf, ph[i] = 0;
dp[x] = 0; push(dp, x);
while(k) {
x = pop(dp);
//printf("%d %d\n", k, x);
/// asa e mai rapid
unsigned end = v[x].size();
for(unsigned i = 0; i < end; ++i)
if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
dp[v[x][i].first] = dp[x] + v[x][i].second;
if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
else push(dp, v[x][i].first);
}
}
}
void ReadData()
{
scanf("%d%d", &n, &m);
scanf("%d", &K);
int i, x, y, z;
c[0] = 1;
for (i = 1; i <= K; ++i)
{
scanf("%d", &c[i]);
poz[c[i]] = i;
}
for (i = 0; i < m; ++i)
{
scanf("%d%d%d", &x, &y, &z);
v[x].push_back(make_pair(y,z));
v[y].push_back(make_pair(x,z));
}
}
*/