Pagini recente » Cod sursa (job #180632) | Cod sursa (job #831229) | Cod sursa (job #2831936) | Cod sursa (job #1839153) | Cod sursa (job #2060092)
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
struct Alex {
bool operator () (const pair<int, int> a, const pair<int, int> b) {
return a.second > b.second;
}
};
const int NMAX = 2000, KMAX = 15, INF = 2 * 1e8;
int n, m, k, x, y, z;
int preteni[KMAX + 5], dist[NMAX + 5][NMAX + 5];
int viz[NMAX + 5], dp[5 + KMAX][5 + (1 << KMAX)];
vector<pair<int, int> > g[NMAX + 2];
vector<int> cities;
priority_queue<pair<int, int>, vector<pair<int, int> >, Alex > q;
void read() {
ifstream cin("ubuntzei.in");
cin >> n >> m >> k;
cities.push_back(1);
for(int i = 1; i <= k; ++i) {
cin >> preteni[i];
cities.push_back(preteni[i]);
}
cities.push_back(n);
for(int i = 1; i <= m; ++i) {
cin >> x >> y >> z;
g[x].push_back({y, z});
g[y].push_back({x, z});
}
}
inline int min(int a, int b) {
return a < b ? a : b;
}
void dijkstra(int start) {
for(int i = 1; i <= n; ++i)
viz[i] = 0, dist[start][i] = INF;
q.push({start, 0});
dist[start][start] = 0;
while(!q.empty()) {
int node = q.top().first;
q.pop();
vector<pair<int, int> >::iterator vecini;
if(!viz[node]) {
for(vecini = g[node].begin(); vecini != g[node].end(); ++vecini) {
if(dist[start][vecini -> first] > dist[start][node] + vecini -> second) {
dist[start][vecini -> first] = dist[start][node] + vecini -> second;
q.push({vecini -> first, dist[start][vecini -> first]});
}
}
}
viz[node] = 1;
}
}
void findDist() {
vector<int>::iterator oras;
for(oras = cities.begin(); oras != cities.end(); ++oras) {
dijkstra(*oras);
}
}
void solve() {
ofstream cout("ubuntzei.out");
if(k == 0) {
cout << dist[1][n] << "\n";
return;
}
int limita = 1 << k;
for(int stare = 1; stare < limita; ++stare) {
for(int i = 1; i <= n; ++i)
dp[i][stare] = INF;
}
for(int i = 1; i <= n; ++i) {
dp[i][1 << (i - 1)] = dist[1][preteni[i]];
}
for(int stare = 1; stare < limita; ++stare) {
for(int i = 1; i <= k; ++i) {
if(stare & (1 << (i - 1)))
for(int j = 1; j <= k; ++j)
if(i != j && stare & (1 << (j - 1)))
dp[i][stare] = min(dp[i][stare], dp[j][stare ^ (1 << (i - 1))] + dist[preteni[i]][preteni[j]]);
}
}
int ans = INF;
for(int i = 1; i <= k; ++i)
ans = min(ans, dp[i][limita - 1] + dist[preteni[i]][n]);
cout << ans << "\n";
}
int main() {
read();
findDist();
solve();
return 0;
}