Pagini recente » Cod sursa (job #3003245) | Cod sursa (job #561815) | Cod sursa (job #2604578) | Cod sursa (job #857347) | Cod sursa (job #2172296)
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int NMAX = 2000;
struct drum
{
int x, dist;
}; vector <drum> g[NMAX + 5]; drum nou;
priority_queue <int, vector <int>, greater <int>> pq;
bool viz[NMAX + 5];
int a[20][NMAX + 5];
int d[33000][20], v[20];
int main()
{
freopen("ubuntzei.in", "r", stdin);
freopen("ubuntzei.out", "w", stdout);
int n, m, k, x, y, cn, dist, ans;
scanf("%d %d %d", &n, &m, &k);
for (int i = 1; i <= k; ++i)
scanf("%d", &v[i]);
for (int i = 1; i <= m; ++i)
{
scanf("%d %d %d", &x, &y, &dist);
nou.dist = dist; nou.x = y;
g[x].push_back(nou);
nou.x = x;
g[y].push_back(nou);
}
memset(a, -1, sizeof(a));
/// Djikstra din "1"
pq.push(1); a[0][1] = 0;
while (!pq.empty())
{
x = pq.top(); pq.pop();
if (viz[x] == 1)
continue;
viz[x] = 1;
for (int i = 0; i < g[x].size(); ++i)
{
y = g[x][i].x; dist = g[x][i].dist;
if (a[0][y] == -1 || dist + a[0][x] < a[0][y])
{
a[0][y] = a[0][x] + dist;
pq.push(y);
}
}
}
memset(viz, 0, sizeof(viz));
/// Djikstra din "n"
pq.push(n); a[k + 1][n] = 0;
while (!pq.empty())
{
x = pq.top(); pq.pop();
if (viz[x] == 1)
continue;
viz[x] = 1;
for (int i = 0; i < g[x].size(); ++i)
{
y = g[x][i].x; dist = g[x][i].dist;
if (a[k + 1][y] == -1 || dist + a[k + 1][x] < a[k + 1][y])
{
a[k + 1][y] = a[k + 1][x] + dist;
pq.push(y);
}
}
}
memset(viz, 0, sizeof(viz));
/// Djikstra din cele k orase
for (int i = 1; i <= k; ++i)
{
pq.push(v[i]); a[i][v[i]] = 0;
while (!pq.empty())
{
x = pq.top(); pq.pop();
if (viz[x] == 1)
continue;
viz[x] = 1;
for (int i = 0; i < g[x].size(); ++i)
{
y = g[x][i].x; dist = g[x][i].dist;
if (a[i][y] == -1 || dist + a[i][x] < a[i][y])
{
a[i][y] = a[i][x] + dist;
pq.push(y);
}
}
}
memset(viz, 0, sizeof(viz));
}
/// Dinamica
for (int i = 1; i <= k; ++i)
d[1 << (i - 1)][i] = a[0][v[i]];
for (int c = 1; c < (1 << k); ++c)
for (int i = 1; i <= k; ++i)
if (c & (1 << (i - 1)) != 0)
for (int j = 1; j <= k; ++j)
if (c & (1 << (j - 1)) == 0)
{
cn = c + (1 << (j - 1));
if(d[cn][j] == 0 || d[c][i] + a[i][v[j]] < d[cn][j])
d[cn][j] = d[c][i] + a[i][v[j]];
}
ans = d[(1 << k) - 1][1] + a[k + 1][1];
for (int i = 2; i <= k; ++i)
ans = min (ans, d[(1 << k) - 1][i] + a[k + 1][i]);
printf("%d\n", ans);
return 0;
}