Pagini recente » Cod sursa (job #3157051) | Cod sursa (job #1927485) | Cod sursa (job #3236074) | Cod sursa (job #2916434) | Cod sursa (job #2176320)
#pragma GCC optimize("03")
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair <int, int>
#define INF 2000000000
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
int n, m, x, y, c, pw, C[20], dp[2010], D[20][2010], bst[16][1 << 17], lim;
vector <pii> v[2010];
set <pii> h;
vector <int> masks[20];
void Dij(int id){
h.clear();
for(int i = 1; i <= n; i++)
dp[i] = INF;
dp[C[id]] = 0;
h.insert({0, C[id]});
while(!h.empty()){
pii dad = *h.begin();
h.erase(h.begin());
for(auto son : v[dad.se]){
if(dad.fi + son.fi < dp[son.se]){
if(dp[son.se] != INF){
h.erase(h.find({dp[son.se], son.se}));
}
dp[son.se] = dad.fi + son.fi;
h.insert({dp[son.se], son.se});
}
}
}
for(int i = 1; i <= n; i++)
D[id][i] = dp[i];
}
void solve(int lvl, int id){
id--;
for(auto mask : masks[lvl]){
if((mask & (1 << id)) == 0)
continue;
int msk = (mask ^ (1 << id));
if(msk == 0){
bst[id + 1][mask] = D[id + 1][1];
continue;
}
for(int bit = 0; bit < pw; ++bit){
if(msk & (1 << bit)){
bst[id + 1][mask] = min(bst[id + 1][mask], bst[bit + 1][msk] + D[id + 1][C[bit + 1]]);
}
}
}
}
int main(){
in >> n >> m;
in >> pw;
for(int i = 1; i <= pw; i++)
in >> C[i];
while(m--){
in >> x >> y >> c;
v[x].push_back({c, y});
v[y].push_back({c, x});
}
for(int i = 1; i <= pw; i++)
Dij(i);
lim = (1 << pw);
for(int mask = 1; mask < lim; ++mask)
masks[__builtin_popcount(mask)].push_back(mask);
for(int i = 1; i <= pw; i++)
for(int j = 0; j < lim; j++)
bst[i][j] = INF;
for(int i = 1; i <= pw; i++)
for(int j = 1; j <= pw; j++)
solve(i, j);
int mn = INF;
for(int i = 1; i <= pw; i++)
mn = min(mn, bst[i][lim - 1] + D[i][n]);
out << mn;
return 0;
}