Pagini recente » Cod sursa (job #3190546) | Cod sursa (job #2394887) | Cod sursa (job #1156674) | Cod sursa (job #1514550) | Cod sursa (job #2048719)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int NMAX = 2000;
const int LMAX = 40000;
const int KMAX = 15;
const int INF = 1 << 30;
struct Edge {
int to;
int cost;
};
struct Data {
int node;
int cost;
bool operator< (Data other) const {
return other.cost > cost;
}
};
int n, m, k, res;
int src, dest;
int v[1 + KMAX];
int dist[1 + KMAX][1 + LMAX];
int a[1 + LMAX][1 + KMAX];
vector < Edge > g[1 + NMAX];
void addedge(int x, int y, int c) {
Edge direct = {y, c};
Edge inverse = {x, c};
g[x].push_back(direct);
g[y].push_back(inverse);
}
void dijkstra(int vnode) {
priority_queue < Data > pq;
for(int i = 0; i <= n; i++)
dist[vnode][i] = INF;
dist[vnode][v[vnode]] = 0;
pq.push({v[vnode], 0});
while(!pq.empty()) {
Data from = pq.top();
pq.pop();
if(from.cost <= dist[vnode][from.node]) {
for(int i = 0; i < g[from.node].size(); i++) {
Data to;
to.node = g[from.node][i].to;
to.cost = g[from.node][i].cost;
if(from.cost + to.cost < dist[vnode][to.node]) {
dist[vnode][to.node] = from.cost + to.cost;
pq.push(to);
}
}
}
}
}
void solve() {
for(int i = 0; i <= LMAX; i++)
for(int j = 0; j <= KMAX; j++)
a[i][j] = INF;
for(int m = 1; m < (1 << k); m++) {
if(! (m & (m - 1))) {
for(int i = 0; i < k; i++)
if(m == (1 << i))
a[m][i] = dist[0][v[i + 1]];
} else {
for(int i = 0; i < k; i++) {
for(int j = 0; j < k; j++) {
if((m & (1 << i)) != 0 && (m & (1 << j)) != 0)
a[m][i] = min(a[m][i], a[m - (1 << i)][j] + dist[j + 1][v[i + 1]]);
}
}
}
}
}
int main()
{
in >> n >> m >> k;
src = 1;
dest = n;
for(int i = 1; i <= k; i++)
in >> v[i];
for(int i = 1; i <= m; i++) {
int x, y, z;
in >> x >> y >> z;
addedge(x, y, z);
}
v[0] = src;
for(int i = 0; i <= k; i++)
dijkstra(i);
solve();
res = INF;
if(k == 0) {
res = dist[0][n];
} else {
for(int i = 0; i < k; i++)
res = min(res, a[(1 << k) - 1][i] + dist[i + 1][n]);
}
out << res << '\n';
in.close();
out.close();
return 0;
}
/*
for(int i = 0; i <= k; i++) {
cout << v[i] <<": ";
for(int j = 1; j <= n; j++) {
if(dist[i][j] != INF)
cout << dist[i][j] << ' ';
else
cout << "-1 ";
}
cout << '\n';
}
*/