#include #include using ll = long long; template std::vector steiner_tree(std::vector>> &G, std::vector &terminal){ const int N = G.size(), t = terminal.size(); if(t == 0) { std::vector ans(N); return ans; } std::vector> dp(1 << t, std::vector(N, std::numeric_limits::max() / 2)); for(int i = 0; i < t; i++){ assert(0 <= terminal[i] && terminal[i] < N); dp[1 << i][terminal[i]] = 0; } std::priority_queue, std::vector>, std::greater>> pq; for(int S = 1; S < (1 << t); S++){ for(int v = 0; v < N; v++){ for(int U = S & (S - 1); U > 0; U = (U - 1) & S){ dp[S][v] = std::min(dp[S][v], dp[U][v] + dp[U ^ S][v]); } } for(int v = 0; v < N; v++) pq.emplace(dp[S][v], v); while(!pq.empty()){ auto [d, v] = pq.top(); pq.pop(); if(d > dp[S][v])continue; for(auto &&[u, w] : G[v]){ if(d + w >= dp[S][u]) continue; dp[S][u] = d + w; pq.emplace(dp[S][u], u); } } } return dp.back(); } using namespace std; int main(){ ios::sync_with_stdio(false); cin.tie(0); int N, M, T; cin >> N >> M >> T; vector ter(T); if(T <= 16){ vector>> G(N); for(int i = 0; i < M; i++){ int u, v, w; cin >> u >> v >> w; u--, v--; G[u].emplace_back(v, w); G[v].emplace_back(u, w); } for(auto &&v : ter) cin >> v, v--; int tmp = ter.back(); ter.pop_back(); cout << steiner_tree(G, ter)[tmp] << '\n'; }else{ vector> edge(M); for(auto &&[u, v, w] : edge){ cin >> u >> v >> w; u--, v--; swap(u, w); } long long S = (1ll << N) - 1; int ans = 1 << 30; for(auto &&v : ter) { cin >> v; v--; S ^= 1ll << v; } sort(edge.begin(), edge.end()); for(long long U = S; U >= 0; U = (U - 1) & S){ int sv = 0; atcoder::dsu uf(N); for(auto &&[w, u, v] : edge){ if((U >> u & 1) || (U >> v & 1) || uf.same(u, v)) continue; uf.merge(u, v); sv += w; } if(uf.size(ter[0]) + __builtin_popcountll(U) == N){ ans = min(ans, sv); } if(U == 0) break; } cout << ans << '\n'; } }