Pagini recente » Cod sursa (job #1180476) | Cod sursa (job #1174366) | Cod sursa (job #1141288) | Cod sursa (job #1898693) | Cod sursa (job #2025985)
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e3 + 5;
const int MAXM = 1e4 + 5;
const int MAXK = 17;
FILE *fin, *fout;
int d[MAXN];
class compare {
public:
bool operator() (int &x, int &y) {
return d[ x ] > d[ y ];
}
};
vector < pair <int, int > > G[MAXN];
priority_queue < int, vector <int>, compare > heap;
int n, m, k, nodes[MAXK], start[MAXN], dist[MAXK][MAXK], best[(1<<(MAXK-1))][MAXK];
inline void dijkstra( int node ) {
for (int i = 1; i <= n; i++)
d[ i ] = INF;
d[ node ] = 0;
while(!heap.empty())
heap.pop();
heap.push( node );
while (!heap.empty()) {
node = heap.top();
heap.pop();
for (pair <int, int> edge: G[ node ])
if (d[ edge.first ] > d[ node ] + edge.second) {
d[ edge.first ] = d[ node ] + edge.second;
heap.push( edge.first );
}
}
}
int main()
{
fin = fopen( "ubuntzei.in", "r" );
fout= fopen( "ubuntzei.out","w" );
int x, y, z;
fscanf( fin, "%d%d%d", &n, &m, &k );
for (int i = 0; i < k; i++)
fscanf( fin, "%d", &nodes[ i ] );
for (int i = 1; i <= m; i++) {
fscanf( fin, "%d%d%d", &x, &y, &z );
G[ x ].push_back( {y, z} );
G[ y ].push_back( {x, z} );
}
dijkstra( 1 );
for (int i = 1; i <= n; i++)
start[ i ] = d[ i ];
if (k == 0) {
fprintf( fout, "%d", start[ n ] );
return 0;
}
for (int i = 0; i < k+1; i++)
for (int j = 0; j < k+1; j++)
dist[ i ][ j ] = INF;
for (int i = 0; i < k; i++) {
dijkstra( nodes[ i ] );
for (int j = 0; j < k; j++)
if (i != j)
dist[ i ][ j ] = d[ nodes[ j ] ];
else
dist[ i ][ j ] = 0;
dist[ i ][ k ] = d[ n ];
}
memset( best, 0x3f, sizeof best );
for (int i = 0; i < k; i++)
best[ (1<<i) ][ i ] = start[ nodes[ i ] ];
for (int i = 1; i < (1<<k); i++)
for (int j = 0; j < k; j++)
if (((1<<j) & i) && best[ i ][ j ] == INF)
for (int t = 0; t < k; t++)
if (t != j && ((1<<t) & i))
best[ i ][ j ] = min( best[ i ][ j ], best[ i-(1<<j) ][ t ] + dist[ t ][ j ] );
int answer = INF;
for (int j = 0; j < k; j++)
answer = min( answer, best[ (1<<k)-1 ][ j ] + dist[ j ][ k ] );
fprintf( fout, "%d", answer );
fclose( fin );
fclose( fout );
return 0;
}