Pagini recente » Cod sursa (job #2051561) | Cod sursa (job #2795547) | Cod sursa (job #1644642) | Cod sursa (job #213632) | Cod sursa (job #1251747)
/// Craciun Catalin
/// Ubuntzei
/// OJI 2011
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#define mp make_pair
const int inf = 1<<30;
const int NMax = 2005;
const int KMax = 18;
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
int n, m, k;
int toVisit[KMax]; /// Nodurile ce trebuie vizitate
int dmin[KMax];
int d[KMax][KMax]; /// d[i][j] = distanta minima de la d[toVisit[i]] la d[toVisit[j]]
int S[1<<KMax][KMax];
vector<int> V[NMax]; /// V[i] = lista cu vecinii lui i
vector<int> C[NMax]; /// C[i] = costul pentru a vizita vecinul i
set< pair<int, int> > q;
inline int minim(int a, int b) { if (a<b) return a; return b; };
inline void addNeighboorToNodeWithCost(int first, int second, int cost) {
V[first].push_back(second); C[first].push_back(cost);
V[second].push_back(first); C[second].push_back(cost);
}
void read() {
f>>n>>m;
f>>k;
for (int i=1;i<=k;i++)
f>>toVisit[i];
for (int i=1;i<=m;i++) {
int x,y,cost; f>>x>>y>>cost;
addNeighboorToNodeWithCost(x,y,cost);
}
f.close();
}
void dijkstra(int source) {
for (int i=1;i<=n;i++) {
dmin[i] = inf;
}
dmin[source] = 0;
q.insert(mp(0,source));
while (!q.empty()) {
int val = (*q.begin()).first; int key = (*q.begin()).second;
q.erase(q.begin());
int neigh = V[key].size();
for (int i=0;i<neigh;i++) {
if (dmin[V[key][i]] > val + C[key][i]) {
dmin[V[key][i]] = val + C[key][i];
q.insert(mp(dmin[V[key][i]], V[key][i]));
}
}
}
}
int main() {
read();
if (!k) {
/// Computing the road from 1 to n, that simple
dijkstra(1);
g<<d[n];
} else {/*
int lim = 1<<k;
toVisit[0] = 1;
for (int i=0;i<=k;i++) {
dijkstra(toVisit[i]);
for (int j=0;j<=k;j++) {
d[i][j] = dmin[ toVisit[ j ] ];
}
d[i][k+1] = dmin[n];
}
for (int i=0;i<=lim;i++) {
for (int j=0;j<=k;j++) {
S[i][j] = inf;
}
}
S[0][0] = 0;
for (int mask=1;mask<lim;mask++) {
for (int i=0;i<k;i++) {
if (mask & (1<<i)) {
int mask2 = mask - (1<<i);
for (int j=0;j<=k;j++) {
S[mask][i+1] = minim(S[mask][i+1], S[mask2][j] + d[j][i+1]);
}
}
}
}
int sol = inf;
for (int i=1;i<=k;i++) {
sol = minim(sol, S[lim-1][i] + d[i][k+1]);
}
g<<sol<<'\n';*/
toVisit[ 0 ] = 1;
for(int i = 0; i <= k; ++i) {
dijkstra( toVisit[i] );
for(int j = 0; j <= k; ++j)
d[i][j] = dmin[ toVisit[j] ];
d[i][k + 1] = dmin[ n ];
}
int lim = ( 1 << k );
for(int mask = 0; mask < lim; ++mask)
for(int i = 0; i <= k; ++i)
S[ mask ][ i ] = inf;
S[ 0 ][ 0 ] = 0;
for(int mask = 1; mask < lim; ++mask)
for(int i = 0; i < k; ++i)
if( mask & ( 1 << i )) {
int mask2 = mask - (1 << i);
for(int j = 0; j <= k; ++j)
S[ mask ][ i + 1 ] = minim( S[mask][ i + 1 ], S[ mask2 ][ j ] + d[ j ][ i + 1 ]);
}
int sol = inf;
for(int i = 1; i <= k; ++i)
sol = min( sol, S[ lim - 1 ][ i ] + d[ i ][ k + 1 ]);
g<<sol<<'\n';
}
g.close();
return 0;
}