Pagini recente » Cod sursa (job #73535) | Cod sursa (job #1325148) | Cod sursa (job #1147809) | Cod sursa (job #822067) | Cod sursa (job #2246362)
#include <queue>
#include <vector>
#include <climits>
#include <fstream>
#include <algorithm>
#define KMAX 15
#define NMAX 2010
using std::sort;
using std::vector;
using std::priority_queue;
std::ifstream fin("ubuntzei.in");
std::ofstream fout("ubuntzei.out");
struct Arc {
int node;
int cost;
};
inline bool operator<(Arc x, Arc y) {
return x.cost > y.cost;
}
int n, m, k;
int c[KMAX];
vector<Arc> ad[NMAX];
vector<int> conf;
int dij[NMAX][NMAX];
int dp[KMAX][1 << KMAX];
bool onPQ[NMAX];
priority_queue<Arc> pq;
void dijkstra(int start) {
pq.push({start, 0});
onPQ[start] = true;
while (!pq.empty()) {
int node = pq.top().node;
pq.pop();
onPQ[node] = false;
for (Arc arc : ad[node])
if (!dij[start][arc.node] || dij[start][node] + arc.cost < dij[start][arc.node]) {
dij[start][arc.node] = dij[start][node] + arc.cost;
if (!onPQ[arc.node]) {
pq.push({arc.node, dij[start][arc.node]});
onPQ[arc.node] = true;
}
}
}
}
int nrBits(int n) {
int ret = 0;
if (n)
do
ret++;
while (n &= (n - 1));
return ret;
}
bool cmp(int x, int y) {
return nrBits(x) < nrBits(y);
}
inline int min(int x, int y) {
return x < y ? x : y;
}
int main() {
fin >> n >> m >> k;
for (int i = 0; i < k; i++)
fin >> c[i];
int x, y, z;
for (int i = 0; i < m; i++) {
fin >> x >> y >> z;
ad[x].push_back({y, z});
ad[y].push_back({x, z});
}
if (!k) {
dijkstra(1);
fout << dij[1][n] << '\n';
fout.close();
return 0;
}
for (int i = 0; i < k; i++)
dijkstra(c[i]);
for (int i = 0; i < k; i++)
dp[i][1 << i] = dij[c[i]][1];
for (int i = 2; i < (1 << k); i++)
if (i & (i - 1))
conf.push_back(i);
sort(conf.begin(), conf.end(), cmp);
for (int mult : conf)
for (int i = 0; i < k; i++)
if (mult & (1 << i)) {
dp[i][mult] = INT_MAX;
int subm = mult - (1 << i);
for (int j = 0; j < k; j++)
if (subm & (1 << j))
dp[i][mult] = min(dp[i][mult], dp[j][subm] + dij[c[i]][c[j]]);
}
int sol = INT_MAX;
for (int i = 0; i < k; i++)
sol = min(sol, dp[i][(1 << k) - 1] + dij[c[i]][n]);
fout << sol << '\n';
fout.close();
return 0;
}