Pagini recente » Cod sursa (job #665909) | Cod sursa (job #2071239) | Cod sursa (job #1855098) | Cod sursa (job #1182457) | Cod sursa (job #1301155)
#include <fstream>
#include <queue>
#include <cstring>
using namespace std;
const int kMaxN = 2005, kMaxK = 17, kMaxConf = 65540, kInf = 0x3f3f3f3f;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int N, M, K, dist[kMaxN], friends[kMaxK], frdist[kMaxK][kMaxK], cdist[kMaxConf][kMaxK];
vector<pair<int, int>> G[kMaxN];
struct HeapMember {
int node, cost;
HeapMember(int n, int c) {
node = n;
cost = c;
}
bool operator<(const HeapMember &other) const {
return cost > other.cost;
}
};
priority_queue<HeapMember> Q;
void Read() {
fin >> N >> M >> K;
for (int i = 0; i < K; ++i)
fin >> friends[i];
friends[K++] = N;
while (M--) {
int x, y, c;
fin >> x >> y >> c;
G[x].push_back(make_pair(y, c));
G[y].push_back(make_pair(x, c));
}
}
void Dijkstra(int source) {
memset(dist, kInf, sizeof dist);
dist[source] = 0;
Q.push(HeapMember(source, 0));
while (!Q.empty()) {
int node = Q.top().node, cost = Q.top().cost;
Q.pop();
if (cost != dist[node])
continue;
for (auto it : G[node]) {
int new_dist = dist[node] + it.second;
if (new_dist < dist[it.first]) {
dist[it.first] = new_dist;
Q.push(HeapMember(it.first, new_dist));
}
}
}
}
int main() {
Read();
Dijkstra(1);
if (K == 1) {
fout << dist[N] << "\n";
return 0;
}
memset(cdist, kInf, sizeof cdist);
for (int i = 0; i < K; ++i)
cdist[1 << i][i] = dist[friends[i]];
for (int i = 0; i < K; ++i) {
Dijkstra(friends[i]);
for (int j = 0; j < K; ++j)
frdist[i][j] = dist[friends[j]];
}
int lim = 1 << K;
for (int i = 3; i < lim; ++i)
for (int j = 0; j < K; ++j)
if (i & (1 << j) && cdist[i][j] == kInf) {
int prev = i ^ (1 << j);
for (int k = 0; k < K; ++k)
if (prev & (1 << k))
cdist[i][j] = min(cdist[i][j], cdist[prev][k] + frdist[k][j]);
}
fout << cdist[lim - 1][K - 1] << "\n";
return 0;
}