Pagini recente » Borderou de evaluare (job #702924) | Cod sursa (job #2543474) | Cod sursa (job #2207999) | Cod sursa (job #3167611) | Cod sursa (job #2374699)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define NMAX 20000
#define KMAX 20
#define inf 0x3f3f3f3f
using namespace std;
ifstream fi("ubuntzei.in");
ofstream fo("ubuntzei.out");
struct Edge{
int node;
int cost;
bool operator < (const Edge & other) const
{
return cost > other.cost;
}
Edge(int aNode, int aCost)
{
node = aNode;
cost = aCost;
}
};
int N, M, K;
int friends[KMAX];
int dp[KMAX][(1 << KMAX)];
int cost[NMAX][NMAX];
vector<Edge> graph[NMAX];
void DoADjikstraFlip(int origin)
{
priority_queue<Edge> q;
q.push({origin, 0});
for(int i = 1; i <= N; ++i)
cost[origin][i] = inf;
cost[origin][origin] = 0;
while(!q.empty())
{
Edge top = q.top();
q.pop();
if(cost[origin][top.node] != top.cost)
continue;
for(auto y: graph[top.node])
{
if(cost[origin][y.node] > top.cost + y.cost)
{
cost[origin][y.node] = top.cost + y.cost;
q.push({y.node, cost[origin][y.node]});
}
}
}
}
int main()
{
fi >> N >> M;
fi >> K;
K += 2;
friends[0] = 1;
friends[K-1] = N;
for(int i = 1; i < K-1; ++i)
fi >> friends[i];
for(int i = 1; i <= M; ++i)
{
int a, b, c;
fi >> a >> b >> c;
graph[a].push_back({b, c});
graph[b].push_back({a, c});
}
for(int i = 0; i < K; ++i)
DoADjikstraFlip(friends[i]);
if(K-2 == 0)
{
fo << cost[1][N];
return 0;
}
for(int i = 0; i < K; ++i)
for(int j = 1; j < (1 << K); ++j)
dp[i][j] = inf;
for(int i = 0; i < K; ++i)
dp[i][1 << i] = cost[1][friends[i]];
for(int i = 1; i < (1 << K); ++i)
for(int j = 0; j < K; ++j)
if((1 << j) & i)
for(int z = 0; z < K; ++z)
if(!((1 << z) & i))
dp[z][i ^ (1 << z)] = min(dp[z][i ^ (1 << z)], dp[j][i] + cost[friends[j]][friends[z]]);
fo << dp[K-1][(1 << K) - 1];
}