Pagini recente » Cod sursa (job #741714) | Cod sursa (job #1467569) | Cod sursa (job #1783645) | Cod sursa (job #2747598) | Cod sursa (job #1016779)
#include<fstream>
#include<vector>
#include<queue>
#include<utility>
#include<string.h>
#include<functional>
using namespace std;
#define dtp unsigned int
#define max_n 760
#define max_k 18
#define max_m 1300
const dtp inf = 4000000000;
ifstream f("gather.in");
ofstream g("gather.out");
dtp k , n , m;
dtp K[max_k] , Find[max_n];
dtp Dr_min[max_k][max_k][max_k] , P[1<<17] , Dist[max_k][1<<17];
bool Fr[max_k][1<<17];
struct coada{
dtp nd , st;
}C[1000000];
struct nd{
dtp next , dist , cap;
};
vector<nd> L[max_n];
void read(){
nd nod;
dtp x , y;
f>>k>>n>>m;
for( dtp i = 1 ; i <= k ; i++ ){
f>>K[i]; Find[K[i]] = i;
}
Find[1] = 0;
for( dtp i = 1 ; i <= m ; i++ ){
f>>x>>y>>nod.dist>>nod.cap;
nod.next = y;
L[x].push_back(nod);
nod.next = x;
L[y].push_back(nod);
}
}
void dijkstra( dtp nod , dtp t ){
pair<dtp , dtp> node;
priority_queue< pair< dtp , dtp > , vector< pair<dtp , dtp> > , greater< pair<dtp , dtp> > > S;
bool Viz[max_n];
dtp i , D[max_n];
memset( D , 0 , sizeof(D) );
memset( Viz , 0 , sizeof(Viz) );
S.push( make_pair(0 , nod) );
while( !S.empty() ){
node = S.top();
S.pop();
if( Viz[ node.second ] )
continue;
D[node.second] = node.first;
Viz[node.second] = true;
for( i = 0 ; i < L[node.second].size() ; i++ ){
if( Viz[L[node.second][i].next] == 0 && L[node.second][i].cap >= t ){
S.push( make_pair( node.first + L[node.second][i].dist , L[node.second][i].next ) );
}
}
}
for( i = 1 ; i <= n ; i++ ){
if( Find[i] != 0 ){
if( D[i] == 0 )
Dr_min[Find[nod]][Find[i]][t] = inf;
else
Dr_min[Find[nod]][Find[i]][t] = D[i];
}
}
}
dtp minim( dtp a , dtp b ){
if( a < b )
return a;
return b;
}
void pre_proc(){
for( dtp i = 1 ; i < (1<<k) ; i++ )
P[i] = P[i/2] + i%2;
for( dtp t , i = 1 ; i <= k ; i++ )
for( t = 0 ; t <= k ; t++ )
dijkstra(K[i] , t);
dijkstra( 1 , 0 );
}
void solve(){
dtp i , j;
dtp nod;
for( i = 1 ; i <= k ; i++ )
for( j = 0 ; j < (1 << k) ; j++ )
Dist[i][j] = inf;
Dist[0][0] = 0;
for( j = 0 ; j < (1<<k) ; j++ ){
for( nod = 0 ; nod <= k ; nod++ ){
if( j != 0 && nod == 0 )
continue;
for( i = 1 ; i <= k ; i++ ){
if( Dist[i][j] > Dist[nod][j] + (P[j]+1)*Dr_min[nod][i][P[j]] ){
Dist[i][j] = Dist[nod][j] + (P[j]+1)*Dr_min[nod][i][P[j]];
}
if( i > 0 && ((1<<(i-1))&j) == 0 && Dist[i][j|(1<<(i-1))] > Dist[nod][j] + (P[j]+1)*Dr_min[nod][i][P[j]] ){
Dist[i][j|(1<<(i-1))] = Dist[nod][j] + (P[j]+1)*Dr_min[nod][i][P[j]];
}
}
}
}
dtp sol = inf;
for( i = 1 ; i <= k ; i++ )
sol = minim(sol , Dist[i][(1<<k)-1]);
g<<sol<<"\n";
}
int main(){
read();
pre_proc();
solve();
return 0;
}