Pagini recente » Cod sursa (job #971377) | Cod sursa (job #2716059) | Cod sursa (job #1572941) | Cod sursa (job #2043340) | Cod sursa (job #1472829)
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#define MAXN 2011
#define MAXK 16
#define INF 0x4fffffff
using namespace std;
int n, m, k;
struct vecin
{
int y, cost;
vecin(int y = 0, int cost = 0) : y(y), cost(cost) {}
bool operator()(vecin a, vecin b)
{
return a.cost > b.cost;
}
};
vector<vecin> graf[MAXN];
int necs[MAXK+1]; // necs 0 is for starting 1 dijkstra
int bests[MAXK+1][MAXN];
void citire()
{
scanf("%d %d", &n, &m);
scanf("%d", &k);
necs[0] = 1;
for (int i = 1; i <= k; i++)
{
scanf("%d", &necs[i]);
}
int x, y, z;
for (int i = 1; i <= m; i++)
{
scanf("%d %d %d", &x, &y, &z);
graf[x].push_back(vecin(y, z));
graf[y].push_back(vecin(x, z));
}
}
priority_queue<vecin, vector<vecin>, vecin> q;
void dijkstra(int start, int best[MAXN])
{
while (!q.empty()) q.pop();
q.push(vecin(start, 0));
for (int i = 0; i <= n; i++)
best[i] = INF;
best[start] = 0;
while (!q.empty())
{
vecin top = q.top();
q.pop();
for (unsigned i = 0; i < graf[top.y].size(); i++)
{
vecin next = graf[top.y][i];
if (best[next.y] > top.cost + next.cost)
{
best[next.y] = top.cost + next.cost;
q.push(vecin(next.y, best[next.y]));
}
}
}
}
int sol[1<<15][MAXK+1];
struct cmp
{
bool operator()(pair<int, int> a, pair<int, int> b)
{
return sol[a.first][a.second] > sol[b.first][b.second];
}
};
priority_queue<pair<int, int>, vector<pair<int, int> >, cmp> q2;
int solve1() // using dijkstra, 75 solution TLE on rest
{
for (int i = 0; i <= k+1; i++)
for (int j = 0; j < (1<<k); j++)
sol[i][j] = INF;
sol[0][0] = 0;
q2.push(make_pair(0, 0));
while (!q2.empty())
{
pair<int, int> top = q2.top();
q2.pop();
if (top.first == k+1)
return sol[k+1][(1<<k)-1];
for (int i = 1; i <= k; i++)
{
if (i == top.first) continue;
int next = i;
int nmult = top.second | (1<<(i-1));
if (sol[next][nmult] > sol[top.first][top.second] + bests[top.first][necs[next]])
{
sol[next][nmult] = sol[top.first][top.second] + bests[top.first][necs[next]];
q2.push(make_pair(next, nmult));
if (nmult == (1<<k)-1 && sol[k+1][(1<<k)-1] > sol[next][nmult] + bests[next][n])
{
sol[k+1][(1<<k)-1] = sol[next][nmult] + bests[next][n];
q2.push(make_pair(k+1, (1<<k)-1));
}
}
}
}
/*int minim = INF;
for (int i = 0; i <= k; i++)
{
if (sol[i][(1<<k)-1] + bests[i][n] < minim)
minim = sol[i][(1<<k)-1] + bests[i][n];
}
return minim;*/
}
int minim(int a, int b) {return a < b ? a : b;}
int solve() // using dynamic programming, 100 solution
{
for (int i = 0; i < (1<<k); i++)
for (int j = 0; j <= k; j++)
sol[i][j] = INF;
sol[0][0] = 0;
for (int i = 1; i < (1<<k); i++)
{
for (int j = 1; j <= k; j++)
{
if (i & (1<<(j-1)))
{
int lasti = i - (1<<(j-1));
for (int p = 0; p <= k; p++)
if (sol[lasti][p] != INF)
sol[i][j] = minim(sol[i][j], sol[lasti][p] + bests[p][necs[j]]);
}
}
}
int rez = INF;
for (int i = 1; i <= k; i++)
rez = minim(rez, sol[(1<<k)-1][i] + bests[i][n]);
return rez;
}
int main()
{
freopen("ubuntzei.in", "r", stdin);
freopen("ubuntzei.out", "w", stdout);
citire();
for (int i = 0; i <= k; i++)
dijkstra(necs[i], bests[i]);
if (k == 0)
printf("%d", bests[0][n]);
else
printf("%d", solve());
return 0;
}