Pagini recente » Cod sursa (job #256631) | Cod sursa (job #3033392) | Cod sursa (job #37117) | Cod sursa (job #2207707) | Cod sursa (job #653404)
Cod sursa(job #653404)
#include <cassert>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define FORIT(it, v) for (typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
#define x first
#define y second
const int MAX_N = 2048;
const int MAX_K = 17;
const int INF = 0x3f3f3f3f;
int n, m, k;
int c[MAX_K];
vector< pair<int, int> > graph[MAX_N];
int dist[MAX_N];
int dmin[MAX_K][MAX_K];
int d[MAX_K][1 << MAX_K];
void dijkstra(int start) {
memset(dist, INF, sizeof(dist));
priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > heap;
heap.push(make_pair(0, start));
while (!heap.empty()) {
pair<int, int> p = heap.top();
heap.pop();
if (dist[p.y] != INF) continue;
dist[p.y] = p.x;
FORIT(it, graph[p.y])
if (dist[it->x] == INF)
heap.push(make_pair(p.x + it->y, it->x));
}
}
inline int bit_count(int x) {
return !x ? 0 : 1 + bit_count(x & (x - 1));
}
int main() {
// read
assert(freopen("ubuntzei.in", "r", stdin));
assert(freopen("ubuntzei.out", "w", stdout));
assert(scanf("%d %d", &n, &m) == 2);
assert(scanf("%d", &k) == 1);
for (int i = 1; i <= k; ++i)
assert(scanf("%d", &c[i]) == 1);
c[0] = 1; c[k + 1] = n;
for (int i = 0; i < m; ++i) {
int a, b, cost;
assert(scanf("%d %d %d", &a, &b, &cost) == 3);
graph[a].push_back(make_pair(b, cost));
graph[b].push_back(make_pair(a, cost));
}
// min distances
for (int i = 0; i <= k + 1; ++i) {
dijkstra(c[i]);
for (int j = 0; j <= k + 1; ++j)
dmin[i][j] = dist[c[j]];
}
// hamiltonian path
memset(d, INF, sizeof(d));
for (int conf = 1; conf < (1 << k); ++conf)
for (int last = 0; last < k; ++last) {
if (((conf >> last) & 1) == 0) continue;
if (bit_count(conf) == 1) {
d[last][conf] = dmin[0][last + 1];
continue;
}
for (int new_last = 0; new_last < k; ++new_last)
if ((conf >> new_last) & 1)
d[last][conf] = min(d[last][conf], d[new_last][conf ^ (1 << last)] + dmin[new_last + 1][last + 1]);
}
// print result
int best = INF;
for (int i = 0; i < k; ++i)
best = min(best, d[i][(1 << k) - 1] + dmin[i + 1][k + 1]);
if (k == 0) best = dmin[0][1];
printf("%d\n", best);
}