Pagini recente » Cod sursa (job #389581) | Cod sursa (job #1640004) | Cod sursa (job #2695111) | Cod sursa (job #2559828) | Cod sursa (job #1392226)
// dp[i][j] = costul minim pentru a ajunge in j trecand cel putin o data prin orasele din multimea i
// dp[i][j] = dp[i-{j}][k]+Dist[j][k] , pentru orice j, k apartinand multimii i
// complexitate finala: O(K*M*log(N)+2^K*K^2)
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define PII pair<int,int>
#define pb push_back
#define mp make_pair
using namespace std;
const int KMAX = 15;
const int NMAX = 2005;
const int INF = 1 << 30;
int K, i, j, k, n, m, p, x, y, c, from, where, costwhere, aux, sol;
int P[KMAX], Dist[NMAX][NMAX], dp[1 << KMAX][KMAX];
vector<PII> V[NMAX];
struct cmp
{
bool operator () (PII a, PII b)
{
return a.second > b.second;
}
};
priority_queue<PII, vector<PII>, cmp> Q;
void Dijkstra(int x)
{
int d[NMAX], i;
for(i = 1; i <= n; i++)
d[i] = INF;
d[x] = 0;
Q.push(mp(x, 0));
while(!Q.empty())
{
from = Q.top().first;
Q.pop();
for(vector<PII>::iterator it = V[from].begin(); it != V[from].end(); it++)
{
where = it->first;
costwhere = it->second;
if(d[from] + costwhere < d[where])
{
d[where] = d[from] + costwhere;
Q.push(mp(where, d[where]));
}
}
}
for(i = 1; i <= n; i++)
Dist[x][i] = d[i];
}
int main()
{
freopen("ubuntzei.in", "r", stdin);
freopen("ubuntzei.out", "w", stdout);
scanf("%d%d%d", &n, &m, &p);
for(i = 0; i < p; i++)
scanf("%d", &P[i]);
for(; m; m--)
{
scanf("%d%d%d", &x, &y, &c);
V[x].pb(mp(y, c));
V[y].pb(mp(x, c));
}
Dijkstra(1);
if(!p)
{
printf("%d\n", Dist[1][n]);
return 0;
}
for(i = 0; i < p; i++)
Dijkstra(P[i]);
K = (1 << p) - 1;
for(i = 1; i <= K; i++)
for(j = 0; j < p; j++)
dp[i][j] = INF;
for(i = 0; i < p; i++)
dp[1 << i][i] = Dist[1][P[i]];
for(i = 1; i <= K; i++)
for(j = 0; j < p; j++)
if((1 << j) & i)
for(k = 0; k < p; k++)
if(((1 << k) & i) && k != j)
{
aux = dp[i - (1 << j)][k] + Dist[P[j]][P[k]];
dp[i][j] = min(dp[i][j], aux);
}
for(sol = INF, i = 0; i < p; i++)
sol = min(sol, dp[K][i] + Dist[P[i]][n]);
printf("%d\n", sol);
return 0;
}