Pagini recente » Cod sursa (job #740279) | Cod sursa (job #3277933) | Cod sursa (job #294184) | Cod sursa (job #430) | Cod sursa (job #653421)
Cod sursa(job #653421)
#include <cstdio>
#include <cstring>
#include <cassert>
#include <queue>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
#define FORIT(it, v) for (typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
#define kkt
const int INF = 0x3f3f3f3f;
const int MAXN = 2013;
const int MAXM = 10013;
const int MAXK = 20;
const int MAXCONF = 32768;
vector< pair<int,int> > G[MAXN];
int N, M, K;
int D[MAXCONF][MAXK], dist[MAXK][MAXN], ubuntzei[MAXK];
void read() {
assert(scanf("%d %d", &N, &M) == 2);
assert(scanf("%d", &K) == 1);
for (int i = 0; i < K; i++)
scanf("%d", &ubuntzei[i]);
int x, y, c;
for (int i = 0; i < M; i++) {
assert(scanf("%d %d %d", &x, &y, &c) == 3);
G[x].push_back( make_pair(y, c) );
G[y].push_back( make_pair(x, c) );
}
}
void dijkstra(int start, int D[]) {
priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > heap;
pair<int, int> top;
int k;
for (int i = 1; i <= N; i++) D[i] = INF;
D[start] = 0;
heap.push( make_pair(0, start) );
for (int i = 0; i < N - 1; i++) {
do {
top = heap.top();
k = top.second;
heap.pop();
} while (D[k] == INF);
FORIT(it, G[k])
if (D[it->first] == INF) {
D[it->first] = min(D[it->first], D[k] + it->second);
heap.push( make_pair(D[it->first], it->first) );
}
}
}
int solve() {
if (!K) {
dijkstra(1, dist[0]);
return dist[0][N];
}
// Compute shortest paths from source + all K ubuntzei.
for (int i = 0; i < K; i++)
dijkstra(ubuntzei[i], dist[i]);
int c, best;
// Compute D[conf, i].
D[0][0] = 0;
for (int conf = 1; conf < (1 << K); conf++) {
for (int i = 0; i < K; i++)
if (conf & (1 << i)) {
// Compute D[conf][i] = min(...)
c = conf ^ (1 << i);
if (c) {
best = INF;
for (int j = 0; j < K; j++)
if (c & (1 << j))
best = min(best, D[c][j] + dist[i][ ubuntzei[j] ]);
D[conf][i] = best;
} else {
D[conf][i] = dist[i][1];
}
}
/*printf("D[%d]: ", conf);
for (int i = 0; i < K; i++)
printf("%d ", D[conf][i]);
printf("\n");*/
}
best = INF;
c = (1 << K) - 1;
for (int i = 0; i < K; i++)
if (c & (1 << i))
best = min(best, D[c][i] + dist[i][N]);
return best;
}
int main() {
assert(freopen("ubuntzei.in", "r", stdin));
assert(freopen("ubuntzei.out", "w", stdout));
read();
printf("%d\n", solve());
return 0;
}