Pagini recente » Cod sursa (job #2620320) | Cod sursa (job #1714256) | Cod sursa (job #1677869) | Cod sursa (job #2104790) | Cod sursa (job #791796)
Cod sursa(job #791796)
#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)
const int INF = 0x3f3f3f3f;
const int K = 17;
const int N = 2005;
int n, m, k;
int orase[K];
int d[1 << K][K], dmin[N][N], dist[N];
vector <pair <int, int> > graf[N];
void read() {
assert(freopen("ubuntzei.in", "r", stdin) != NULL);
assert(scanf("%d %d %d", &n, &m, &k) == 3);
for (int i = 1; i <= k; ++i)
assert(scanf("%d", &orase[i]) == 1);
orase[0] = 1;
orase[k + 1] = n;
for (int i = 1; i <= m; ++i) {
int x, y, z;
assert(scanf("%d %d %d", &x, &y, &z) == 3);
graf[x].push_back(make_pair(y, z));
graf[y].push_back(make_pair(x, z));
}
}
void dijkstra(int source) {
memset(dist, INF, sizeof(dist));
priority_queue <pair <int, int>, vector <pair <int, int> >, greater <pair <int, int> > > heap;
heap.push(make_pair(0, source));
while (!heap.empty()) {
pair <int, int> nodCurent = heap.top();
heap.pop();
if (dist[nodCurent.second] != INF)
continue;
dist[nodCurent.second] = nodCurent.first;
FORIT(it, graf[nodCurent.second])
if (dist[it->first] == INF)
heap.push(make_pair(nodCurent.first + it->second, it->first));
}
}
void minDist() {
for (int i = 0; i <= k + 1; ++i) {
dijkstra(orase[i]);
for (int j = 0; j <= k + 1; ++j)
dmin[i][j] = dist[orase[j]];
}
/*for (int i = 0; i <= k + 1; ++i) {
for (int j = 0; j <= k + 1; ++j)
printf("%d ", dmin[i][j]);
printf("\n");
}
*/
}
int biti(int x) {
return !x ? 0 : 1 + biti(x & (x - 1));
}
inline void update_min(int &a, int b) {
a = a < b ? a : b;
}
void dinamica() {
memset(d, INF, sizeof(d));
for (int conf = 1; conf < (1 << k); ++conf)
for (int last = 0; last < k; ++last) {
if (!(conf & (1 << last)))
continue;
if (biti(conf) == 1)
d[conf][last] = dmin[0][last + 1];
for (int newLast = 0; newLast < k; ++newLast) {
if (conf & (1 << newLast))
continue;
d[conf | (1 << newLast)][newLast] = min(d[conf | (1 << newLast)][newLast], d[conf][last] + dmin[last + 1][newLast + 1]);
// update_min(d[conf | (1 << newLast)], d[conf][last] + dmin[last + 1][newLast + 1]);
}
}
}
void print() {
assert(freopen("ubuntzei.out", "w", stdout) != NULL);
int sol = INF;
for (int i = 0; i < k; ++i)
sol = min(sol, d[(1 << k) - 1][i] + dmin[i + 1][k + 1]);
if (k == 0)
sol = d[0][1];
printf("%d\n", sol);
}
int main() {
read();
minDist();
dinamica();
print();
}