Pagini recente » Cod sursa (job #3351923) | Cod sursa (job #3335814) | Cod sursa (job #3335622) | Cod sursa (job #3351152) | Cod sursa (job #3338283)
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <algorithm>
#include <cstring>
using namespace std;
ifstream cin("ubuntzei.in");
ofstream cout("ubuntzei.out");
struct heapNode {
int node;
int cost;
bool operator < (const heapNode& a) const {
return cost > a.cost;
}
};
const int MAXN = 2005;
const int MAXK = 17;
const int INF = 1000000000;
vector<heapNode> graph[MAXN];
int dist[MAXK][MAXN];
int toSpecial[MAXN];
int fromSpecial[MAXK];
int specialDist[MAXK][MAXK];
int k;
int dp[1 << 15][15];
void dijkstra(int start, int idx, int n) {
for (int i = 1; i <= n; i++) {
dist[idx][i] = INF;
}
dist[idx][start] = 0;
priority_queue<heapNode> pq;
pq.push({start, 0});
while (!pq.empty()) {
heapNode current = pq.top();
pq.pop();
if (current.cost != dist[idx][current.node]) {
continue;
}
for (auto& edge : graph[current.node]) {
int neighbor = edge.node;
int newCost = current.cost + edge.cost;
if (newCost < dist[idx][neighbor]) {
dist[idx][neighbor] = newCost;
pq.push({neighbor, newCost});
}
}
}
}
int main() {
int n, m;
cin >> n >> m >> k;
vector<int> specials(k);
for (int i = 0; i < k; i++) {
cin >> specials[i];
}
vector<int> allSpecials;
allSpecials.push_back(1);
for (int i = 0; i < k; i++) {
allSpecials.push_back(specials[i]);
}
allSpecials.push_back(n);
int totalSpecial = allSpecials.size();
for (int i = 0; i < m; i++) {
int x, y, z;
cin >> x >> y >> z;
graph[x].push_back({y, z});
graph[y].push_back({x, z});
}
memset(toSpecial, -1, sizeof(toSpecial));
for (int i = 0; i < totalSpecial; i++) {
fromSpecial[i] = allSpecials[i];
toSpecial[allSpecials[i]] = i;
}
for (int i = 0; i < totalSpecial; i++) {
dijkstra(allSpecials[i], i, n);
}
if (k == 0) {
cout << dist[0][n] << "\n";
return 0;
}
for (int i = 0; i < totalSpecial; i++) {
for (int j = 0; j < totalSpecial; j++) {
specialDist[i][j] = dist[i][fromSpecial[j]];
if (specialDist[i][j] >= INF) {
specialDist[i][j] = INF;
}
}
}
int maskCount = (1 << k);
for (int mask = 0; mask < maskCount; mask++) {
for (int last = 0; last < k; last++) {
dp[mask][last] = INF;
}
}
for (int i = 0; i < k; i++) {
dp[1 << i][i] = specialDist[0][i + 1];
}
for (int mask = 0; mask < maskCount; mask++) {
for (int last = 0; last < k; last++) {
if (dp[mask][last] >= INF) continue;
for (int next = 0; next < k; next++) {
if (mask & (1 << next)) continue;
int newMask = mask | (1 << next);
int newCost = dp[mask][last] + specialDist[last + 1][next + 1];
if (newCost < dp[newMask][next]) {
dp[newMask][next] = newCost;
}
}
}
}
int answer = INF;
int endIndex = totalSpecial - 1;
for (int last = 0; last < k; last++) {
if (dp[maskCount - 1][last] >= INF) continue;
int totalCost = dp[maskCount - 1][last] + specialDist[last + 1][endIndex];
if (totalCost < answer) {
answer = totalCost;
}
}
if (answer >= INF) {
answer = -1;
}
cout << answer << "\n";
return 0;
}