Pagini recente » Cod sursa (job #2386852) | Cod sursa (job #2109038) | Cod sursa (job #2938573) | Cod sursa (job #2972948) | Cod sursa (job #2812316)
#define d(x) std::cout << x << std::endl
#define dm(msg, x) std::cout << msg << x << std::endl
#define all(a) a.begin(), a.end()
#define range(a, l, r) a.begin() + l, a.begin() + r
#define aall(a, n) a + 1, a + 1 + n
#define arange(a, l, r) a + l, a + r
#define maxself(a, b) a = std::max(a, b);
#define minself(a, b) a = std::min(a, b);
#define inout(f) std::ifstream in((f) + (std::string) ".in");std::ofstream out((f) + (std::string) ".out")
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
const int NMAX = 2e3;
const int KMAX = 15;
const int INF = 1e9 + 7;
class QElem {
public:
int node, dist;
QElem() = default;
QElem(int node, int dist):
node(node), dist(dist) {};
bool operator < (const QElem& other) const {
return dist < other.dist;
}
bool operator > (const QElem& other) const {
return dist > other.dist;
}
};
class Edge {
public:
int node, cost;
Edge() = default;
Edge(int node, int cost):
node(node), cost(cost) {};
};
int n, m;
std::vector<Edge> graph[1 + NMAX];
std::vector<Edge> compressedGraph[1 + NMAX];
int k;
std::vector<int> targets;
std::priority_queue<QElem, std::vector<QElem>, std::greater<QElem>> pq;
int dist[1 + KMAX + 1][1 + NMAX];
int hamilton[1 << (1 + KMAX)][1 + KMAX];
void dijkstra(int srcIndex) {
int src = targets[srcIndex];
dist[srcIndex][src] = 0;
pq.emplace(src, 0);
while (!pq.empty()) {
auto front = pq.top();
pq.pop();
if (front.dist > dist[srcIndex][front.node])
continue;
for (auto& edge : graph[front.node]) {
int newDist = front.dist + edge.cost;
if (dist[srcIndex][edge.node] == -1 || dist[srcIndex][edge.node] > newDist) {
dist[srcIndex][edge.node] = newDist;
pq.emplace(edge.node, newDist);
}
}
}
}
int main() {
inout("ubuntzei");
in >> n >> m;
in >> k;
targets.resize(k + 2);
targets[0] = 1;
for (int i = 1; i <= k; ++i)
in >> targets[i];
targets[k + 1] = n;
for (int i = 1; i <= m; ++i) {
int x, y, z;
in >> x >> y >> z;
graph[x].emplace_back(y, z);
graph[y].emplace_back(x, z);
}
memset(dist, -1, sizeof(dist));
for (int i = 0; i <= k + 1; ++i)
dijkstra(i);
for (int i = 0; i <= k + 1; ++i) {
for (int j = i + 1; j <= k + 1; ++j) {
compressedGraph[i].emplace_back(j, dist[i][targets[j]]);
compressedGraph[j].emplace_back(i, dist[j][targets[i]]);
}
}
// hamilton
for (int mask = 0; mask < (1 << (k + 1)); ++mask) {
for (int last = 0; last < k + 1; ++last) {
hamilton[mask][last] = INF;
}
}
hamilton[1][0] = 0;
for (int mask = 0; mask < (1 << (k + 1)); ++mask) {
for (int last = 0; last < k + 1; ++last) {
if (!(mask & (1 << last)))
continue;
int newMask = mask ^ (1 << last);
for (auto& edge: compressedGraph[last]) {
if (mask & (1 << edge.node)) {
if (hamilton[newMask][edge.node] + edge.cost < hamilton[mask][last])
hamilton[mask][last] = hamilton[newMask][edge.node] + edge.cost;
}
}
}
}
int best = INF;
for (int i = 0; i <= k; ++i)
best = std::min(best, hamilton[(1 << (k + 1)) - 1][i] + dist[k + 1][targets[i]]);
out << best << '\n';
return 0;
}