Pagini recente » Cod sursa (job #2217095) | Cod sursa (job #265216) | Cod sursa (job #2730290) | Cod sursa (job #2337810) | Cod sursa (job #3310526)
#include <iostream>
#include <fstream>
#include <stdint.h>
#include <vector>
#include <queue>
const int64_t MAX_N = 2000;
const int64_t MAX_K = 15;
const int64_t MAX_K_MASK = 1 << MAX_K;
const int64_t MAX_DIST = 1000000000000000000;
int64_t n, m, k;
std::vector<std::pair<int64_t, int64_t>> adj[MAX_N];
int64_t points[MAX_K];
std::priority_queue<std::pair<int64_t, int64_t>> q;
int64_t dists[MAX_N];
int64_t startDists[MAX_K], endDists[MAX_K], pairDists[MAX_K][MAX_K];
int64_t dp[MAX_K_MASK][MAX_K];
int64_t min(int64_t x, int64_t y) {
return (x < y) ? x : y;
}
void Dijkstra(int64_t start) {
for(int64_t i = 0; i != n; ++i)
dists[i] = MAX_DIST;
dists[start] = 0;
q.push({ 0, start });
while(!q.empty()) {
std::pair<int64_t, int64_t> val = q.top();
q.pop();
if(val.first != dists[val.second])
continue;
for(std::pair<int64_t, int64_t> edge : adj[val.second]) {
int64_t newDist = val.first + edge.second;
if(newDist < dists[edge.first]) {
dists[edge.first] = newDist;
q.push({ newDist, edge.first });
}
}
}
}
int main() {
std::ifstream fin("ubuntzei.in");
std::ofstream fout("ubuntzei.out");
fin >> n >> m;
fin >> k;
for(int64_t i = 0; i != k; ++i) {
fin >> points[i];
--points[i];
}
for(int64_t i = 0; i != m; ++i) {
int64_t x, y, z;
fin >> x >> y >> z;
--x; --y;
adj[x].push_back({ y, z });
adj[y].push_back({ x, z });
}
if(!k) {
Dijkstra(0);
fout << dists[n - 1];
fin.close();
fout.close();
return 0;
}
Dijkstra(0);
for(int64_t i = 0; i != k; ++i)
startDists[i] = dists[points[i]];
Dijkstra(n - 1);
for(int64_t i = 0; i != k; ++i)
endDists[i] = dists[points[i]];
for(int64_t i = 0; i != k; ++i) {
Dijkstra(points[i]);
for(int64_t j = 0; j != k; ++j)
pairDists[i][j] = dists[points[j]];
}
for(int64_t mask = 0; mask != (1 << k); ++mask) {
for(int64_t i = 0; i != k; ++i)
dp[mask][i] = MAX_DIST;
}
for(int64_t i = 0; i != k; ++i)
dp[1 << i][i] = startDists[i];
for(int64_t mask = 1; mask != (1 << k); ++mask) {
if(!(mask & (mask - 1)))
continue;
for(int64_t i = 0; i != k; ++i) {
if(!(mask & (1 << i)))
continue;
int64_t prevMask = mask ^ (1 << i);
for(int64_t j = 0; j != k; ++j) {
if(!(prevMask & (1 << j)))
continue;
dp[mask][i] = min(dp[mask][i], dp[prevMask][j] + pairDists[j][i]);
}
}
}
int64_t res = MAX_DIST;
for(int64_t i = 0; i != k; ++i)
res = min(res, dp[(1 << k) - 1][i] + endDists[i]);
fout << res;
fin.close();
fout.close();
return 0;
}