Pagini recente » Cod sursa (job #2246782) | Cod sursa (job #2404350) | Cod sursa (job #615258) | Cod sursa (job #1115579) | Cod sursa (job #1977565)
#include <bits/stdc++.h>
#define pb push_back
#define f first
#define s second
#define pii pair<int, int>
#define mp make_pair
using namespace std;
const string name = "ubuntzei",
in_file = name + ".in",
out_file = name + ".out";
ifstream fin(in_file);
ofstream fout(out_file);
const int NMAX = 2e3 + 1, MMAX = 1e4 + 1, KMAX = 16, INF = (1LL << 31) - 1;
struct Edge {
int node;
int cost;
Edge(int node, int cost) {
this->node = node;
this->cost = cost;
}
};
int n, m, k;
int cities[KMAX];
int dist_from_start[NMAX];
int dist_from_finish[NMAX];
int dist[KMAX][NMAX];
int dp[(1 << KMAX)];
bitset<NMAX> visited;
vector<Edge> graph[NMAX];
priority_queue<pii, vector<pii>, greater<pii>> pqueue;
void clear_queue() {
while (!pqueue.empty()) {
pqueue.pop();
}
}
void dijkstra(int source, int dist[]) {
clear_queue();
for (int i = 1; i <= n; i++) {
dist[i] = (i == source ? 0 : INF);
}
visited = 0;
pqueue.emplace(dist[source], source);
while (!pqueue.empty()) {
int node = pqueue.top().s;
pqueue.pop();
if (visited[node]) {
continue;
}
visited[node] = 1;
for (Edge adj : graph[node]) {
if (adj.cost + dist[node] < dist[adj.node]) {
dist[adj.node] = adj.cost + dist[node];
pqueue.emplace(dist[adj.node], adj.node);
}
}
}
}
bool power_of_two(int nr) {
return (nr & (nr - 1)) == 0;
}
int log_base_2(int nr) {
int cnt = 1;
while (nr > 1) {
nr /= 2;
cnt++;
}
return cnt;
}
int main() {
fin >> n >> m >> k;
for (int i = 1; i <= k; i++) {
fin >> cities[i];
}
for (int x, y, c, i = 1; i <= m; i++) {
fin >> x >> y >> c;
graph[x].emplace_back(y, c);
graph[y].emplace_back(x, c);
}
dijkstra(1, dist_from_start);
dijkstra(n, dist_from_finish);
for (int i = 1; i <= k; i++) {
dijkstra(cities[i], dist[i]);
}
if (!k) {
cout << dist_from_start[n];
return 0;
}
int max_mask = (1 << k) - 1;
for (int i = 1; i <= max_mask; i++) {
dp[i] = INF;
}
for (int mask = 1; mask <= max_mask; mask++) {
if (!power_of_two(mask)) {
for (int first_bit = 0; first_bit < k; first_bit++) {
if (mask & (1 << first_bit)) {
for (int second_bit = 0; second_bit < k; second_bit++) {
if (first_bit == second_bit) {
continue;
}
if (mask & (1 << second_bit)) {
int additional = 0;
if (mask == max_mask) {
additional = dist_from_finish[cities[second_bit + 1]];
}
dp[mask] = min(dp[mask],
dp[mask - (1 << first_bit)] + dist[first_bit + 1][cities[second_bit + 1]] + additional);
}
}
}
}
} else {
dp[mask] = dist_from_start[cities[log_base_2(mask)]];
if (mask == max_mask) {
dp[mask] += dist_from_finish[cities[log_base_2(mask)]];
}
}
}
fout << dp[max_mask];
return 0;
}