Pagini recente » Cod sursa (job #445805) | Cod sursa (job #453910) | Cod sursa (job #1300307) | Cod sursa (job #2772429) | Cod sursa (job #1580822)
#include <cstdio>
#include <deque>
#include <vector>
#include <algorithm>
#include <bitset>
#define value first
#define cost second.first
#define maxim second.second
const int EXP = 1 << 4;
const int DIM = 1 << 10;
const long long INF = 1000000000000000LL;
using namespace std;
int V[EXP], K, N, M, X, Y, Z, T, NrBit[1 << EXP]; long long Dist[EXP + 1][EXP][EXP], D[1 << EXP][EXP], Distance[DIM];
vector <pair <int, pair <int, int> > > E[DIM]; bitset <DIM> Marked; deque <int> Queue; long long minim;
void bellman_ford( int start, int val_maxim ) {
for( int i = 0; i < N; i ++ )
Distance[i] = INF;
Distance[start] = 0;
Queue.clear(); Queue.push_back( start );
Marked.reset(); Marked[start] = 1;
while( !Queue.empty() ) {
int node = Queue.front();
vector <pair <int, pair <int, int> > > :: iterator it;
for( it = E[node].begin(); it != E[node].end(); it ++ ) {
pair <int, pair <int, int> > next_node = *it;
if( next_node.maxim >= val_maxim ) {
if( Distance[next_node.value] > Distance[node] + next_node.cost ) {
Distance[next_node.value] = Distance[node] + next_node.cost;
if( !Marked[next_node.value] ) {
Marked[next_node.value] = 1;
Queue.push_back( next_node.value );
}
}
}
}
Marked[node] = 0;
Queue.pop_front();
}
return;
}
int main () {
freopen( "gather.in" , "r", stdin );
freopen( "gather.out", "w", stdout );
scanf( "%d %d %d", &K, &N, &M );
for( int i = 1; i <= K; i ++ ) {
scanf( "%d", &X );
V[i] = X - 1;
} K ++;
for( int i = 1; i <= M; i ++ ) {
scanf( "%d %d %d %d", &X, &Y, &Z, &T );
E[X - 1].push_back( make_pair( Y - 1, make_pair( Z, T + 1 )));
E[Y - 1].push_back( make_pair( X - 1, make_pair( Z, T + 1 )));
}
for( int k = 1; k <= 16; k ++ ) {
for( int i = 0; i < K; i ++ ) {
bellman_ford( V[i], k );
for( int j = 0; j < K; j ++ )
Dist[k][i][j] = Distance[V[j]] * 1LL * k;
}
}
for( int mask = 1; mask < (1 << K); mask ++ )
for( int i = 0; i < K; i ++ )
D[mask][i] = INF;
D[1][0] = 0;
for( int i = 1; i < (1 << K); i ++ )
NrBit[i] = NrBit[i / 2] + (i % 2);
for( int mask = 1; mask < (1 << K); mask ++ ) {
for( int i = 0; i < K; i ++ ) {
if( !((mask >> i) & 1) )
continue;
for( int j = 0; j < K; j ++ ) {
if( ((mask >> j) & 1) )
continue;
if( D[mask + (1 << j)][j] > D[mask][i] + Dist[NrBit[mask]][i][j] )
D[mask + (1 << j)][j] = D[mask][i] + Dist[NrBit[mask]][i][j];
}
}
}
minim = INF;
for( int i = 1; i < K; i ++ ) {
if( minim > D[(1 << K) - 1][i] )
minim = D[(1 << K) - 1][i];
}
printf( "%lld\n", minim );
return 0;
}