Pagini recente » Cod sursa (job #1619746) | Cod sursa (job #2316612) | Cod sursa (job #51687) | Cod sursa (job #432470) | Cod sursa (job #1016500)
#include<fstream>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<utility>
#include<string.h>
#include<functional>
using namespace std;
#define dtp int
#define max_n 760
#define max_k 18
#define max_m 1300
#define inf 1000000000
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];
dtp C[max_m];
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;
}
K[++k] = 1; Find[K[k]] = k;
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);
//for( int j = 1 ; j <= k ; j++ )
// cout<<Dr_min[i][j][t]<<" ";
//cout<<"\n";
}
//cout<<"\n";
}
}
void solve(){
dtp i , j;
dtp p , u;
dtp nod; bool Fr[max_k];
memset(Fr , 0 , sizeof(Fr));
for( i = 1 ; i <= k ; i++ )
for( j = 0 ; j < (1 << (k-1)) ; j++ )
Dist[i][j] = inf;
Dist[k][0] = 0;
p = u = 1;
C[p] = k;
while( p <= u ){
nod = C[p];Fr[nod] = 0;
for( j = 0 ; j < ( 1<<(k-1) ) ; j++ ){
if( Dist[nod][j] == inf )
continue;
for( i = 1 ; i <= k ; i++ ){
if( nod == i )
continue;
if( Dr_min[nod][i][P[j]] == inf )
continue;
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(Fr[i] == 0)
C[++u] = i , Fr[i] = 1;
}
if( i < k && ((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]];
if(Fr[i] == 0)
C[++u] = i , Fr[i] = 1;
}
}
}
p++;
}
dtp sol = inf;
for( i = 1 ; i < k ; i++ )
sol = minim(sol , Dist[i][(1<<(k-1))-1]);
g<<sol<<"\n";
}
int main(){
read();
pre_proc();
solve();
return 0;
}