Pagini recente » Cod sursa (job #2613336) | Cod sursa (job #1719895) | Cod sursa (job #1544143) | Cod sursa (job #1697428) | Cod sursa (job #2630843)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int n, m, k, need[15], d_min[2010][2010], d_part[33000][15];
vector<pair<int, int> > edges[2010];
void dijkstra(int);
bool e_putere_a_lui_2(int);
int main() {
fin >> n >> m >> k;
for (int i = 0; i < k; i++)
fin >> need[i];
for (int i = 1; i <= m; i++) {
int a, b, cost;
fin >> a >> b >> cost;
edges[a].emplace_back(b, cost);
edges[b].emplace_back(a, cost);
}
/// calculam distantele dintre noduri
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
d_min[i][j] = 2e9;
dijkstra(1);
dijkstra(n);
for (int i = 0; i < k; i++)
dijkstra(need[i]);
/// pentru fiecare set de noduri in care trebuie sa mergem
/// calculam distanta minima pe care o parcurgem ca sa
/// trecem prin toate acele noduri si sa ajungem in fiecare dintre ele
int set_complet = (1 << k) - 1;
for (int i = 1; i <= set_complet; i++)
for (int j = 0; j < k; j++)
d_part[i][j] = 1e9;
int last_node = -1;
for (int set_act = 1; set_act <= set_complet; set_act++)
if (e_putere_a_lui_2(set_act)) {
last_node++;
d_part[set_act][last_node] = d_min[1][need[last_node]];
} else
for (int nod_exclus = 0; (1 << nod_exclus) <= set_act; nod_exclus++)
if ((1 << nod_exclus) & set_act)
for (int end_nod_ant = 0; end_nod_ant <= last_node; end_nod_ant++)
if ((1 << end_nod_ant) & set_act)
if (nod_exclus != end_nod_ant)
d_part[set_act][nod_exclus] = min(d_part[set_act][nod_exclus], d_part[set_act - (1 << nod_exclus)][end_nod_ant] + d_min[need[nod_exclus]][need[end_nod_ant]]);
int d_tot = 1e9;
for (int i = 0; i <= last_node; i++)
d_tot = min(d_tot, d_part[set_complet][i] + d_min[n][need[i]]);
if (k == 0)
d_tot = d_min[1][n];
fout << d_tot << '\n';
return 0;
}
bool e_putere_a_lui_2(int x) {
return ((x ^ (x - 1)) & x) == x;
}
void dijkstra(int start) {
priority_queue<pair<int, int> > pq;
pq.push(make_pair(0, start));
d_min[start][start] = 0;
while (!pq.empty()) {
int d_act = -pq.top().first;
int nod_act = pq.top().second;
pq.pop();
if (d_min[start][nod_act] < d_act)
continue;
for (pair<int, int> way : edges[nod_act])
if (d_min[start][way.first] > d_act + way.second) {
d_min[start][way.first] = d_act + way.second;
pq.push(make_pair(-d_min[start][way.first], way.first));
}
}
}