Pagini recente » Cod sursa (job #811558) | Cod sursa (job #2887337) | Cod sursa (job #65861) | Cod sursa (job #322258) | Cod sursa (job #1876322)
#include <fstream>
#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <bitset>
#define N 2001
#define K 17
#define iter vector<pair<int, int> >::iterator
#define val first
#define cost second
#define INF 0x3f3f3f3f
using namespace std;
vector<pair<int, int> > L[N];
int C[N], O[K];
int D[K][N], R[1 << K][K];
struct Comp {
bool operator()(int a, int b) {
return C[a] > C[b];
}
};
priority_queue<int, vector<int>, Comp> Q;
void dijkstra(int pos, int n) {
bitset<N> E;
int node = O[pos];
for (int i = 1; i <= n; ++i)
C[i] = INF;
C[node] = 0;
for (Q.push(node); !Q.empty(); Q.pop()) {
int head = Q.top();
E[head] = 0;
for (iter it = L[head].begin(); it != L[head].end(); ++it) {
int nc = C[head] + it -> cost;
if (nc < C[it -> val]) {
C[it -> val] = nc;
if (!E[it -> val]) {
Q.push(it -> val);
E[it -> val] = 1;
}
}
}
}
for (int j = 1; j <= n; ++j)
D[pos][j] = C[j];
}
void calculate(int n, int k) {
int min = INF;
for (int i = 1; i <= k; ++i) {
// Construct the set without i
int set = 0;
for (int j = 1; j <= k; ++j)
if (j != i)
set += 1 << (C[j] - 1);
// Go through the possibilities of finishing on node O[C[j]]
int nset = set + (1 << (C[i] - 1));
for (int j = 1; j <= k; ++j)
if (j != i) {
int nc = R[set][C[j]] + D[C[j]][O[C[i]]];
if (nc < R[nset][C[i]])
R[nset][C[i]] = nc;
}
}
}
void comb(int l, int n, int k) {
if (l <= k)
for (int i = C[l - 1] + 1; i <= n - k + l; ++i) {
C[l] = i;
if (l == k){
calculate(n, k);
} else
comb(l + 1, n, k);
}
}
int main() {
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int n, m, k;
fin >> n >> m >> k;
for (int i = 2; i <= k + 1; ++i) {
fin >> O[i];
}
O[1] = 1;
for (int i = 1; i <= m; ++i) {
int a, b, c;
fin >> a >> b >> c;
L[a].push_back(make_pair(b, c));
L[b].push_back(make_pair(a, c));
}
for (int i = 1; i <= k + 1; ++i)
dijkstra(i, n);
for (int i = 1; i < 1 << (k + 1); ++i)
for (int j = 1; j <= k + 1; ++j)
R[i][j] = INF;
for (int step = 2, i = 2; i <= k + 1; step <<= 1, ++i)
R[step][i] = D[1][O[i]];
C[0] = 1;
for (int i = 2; i <= k + 1; ++i) {
comb(1, k + 1, i);
}
int minn = INF;
int set = (1 << (k + 1)) - 2;
for (int i = 2; i <= k + 1; ++i) {
int nc = R[set][i] + D[i][n];
if (nc < minn)
minn = nc;
}
fout << minn << "\n";
return 0;
}