Pagini recente » Cod sursa (job #2585117) | Cod sursa (job #1385180) | Cod sursa (job #852346) | Cod sursa (job #1102733) | Cod sursa (job #1077775)
// Dijkstra cu heap ,,de mana", O(K! + N * M * logN)
#include <algorithm>
#include <fstream>
#include <cstring>
#include <queue>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
#define nmax 204
#define inf 0x3f3f3f3f
#define T (u >> 1)
#define L (u << 1)
#define R (L | 1)
struct nod {
int u;
int l;
nod *next;
};
nod *v[nmax];
inline void add(int i, int j, int leg) {
nod *p = new nod;
p->u = j;
p->l = leg;
p->next = v[i];
v[i] = p;
}
int i, n, m, K;
int a, b, lg;
int x, dim;
int c[nmax];
int H[nmax];
int d[nmax][nmax];
inline void upheap(int u) {
while (u != 1 && d[i][H[u]] < d[i][H[T]]) swap(H[u], H[T]), u = T;
}
inline void downheap(int u) {
while (1) {
int m = u;
if (L <= dim && d[i][H[L]] < d[i][H[u]]) m = L;
if (R <= dim && d[i][H[R]] < d[i][H[u]]) m = R;
if (m == u)
break;
swap(H[u], H[m]);
m = u;
}
}
int Used[16];
int st[16];
int min_lg = inf;
int ans = inf;
int cnt;
void back(int k) {
if (cnt + (K - k + 1) * min_lg > ans) return;
if (k == K + 1) {
cnt += d[n][ c[st[k - 1]] ];
if (cnt < ans)
ans = cnt;
cnt -= d[n][ c[st[k - 1]] ];
}
else {
for (int i = 1; i <= K; ++i) {
if (!Used[i]) {
Used[i] = 1;
st[k] = i;
cnt += d[ c[st[k - 1]] ][ c[i] ];
back(k + 1);
Used[i] = 0;
cnt -= d[ c[st[k - 1]] ][ c[i] ];
}
}
}
}
int main() {
fin >> n >> m;
fin >> K;
for (i = 1; i <= K; ++i) fin >> c[i];
for (i = 1; i <= m; ++i) {
fin >> a >> b >> lg;
min_lg = min(min_lg, lg);
add(a, b, lg);
add(b, a, lg);
}
memset(d, inf, sizeof(d));
for (i = 1; i <= n; ++i) {
d[i][i] = 0;
dim = 1;
H[1] = i;
while (dim) {
x = H[1];
for (nod *it = v[x]; it; it = it->next) {
if (d[i][x] + it->l < d[i][it->u]) {
d[i][it->u] = d[i][x] + it->l;
++dim;
H[dim] = it->u;
upheap(dim);
}
}
swap(H[1], H[dim]);
--dim;
downheap(1);
}
if (!K) {
ans = d[1][n];
break;
}
}
c[0] = 1;
if (K) back(1);
fout << ans << '\n';
return 0;
}