Pagini recente » Cod sursa (job #1552594) | Cod sursa (job #2446673) | Cod sursa (job #2329277) | Cod sursa (job #2439923) | Cod sursa (job #810885)
Cod sursa(job #810885)
#include<stdio.h>
#include<vector>
#include<queue>
#define maxk 17
#define maxn 755
#define pb push_back
#define mp make_pair
using namespace std;
FILE*f=fopen("gather.in","r");
FILE*g=fopen("gather.out","w");
const long long inf = (1LL<<62);
int k,n,m;
int where[maxk],which[maxn],T[maxn],biti[1<<(maxk-2)];
long long dist[maxn],D[maxk][maxk][maxn],best[maxk][1<<(maxk-2)];
queue<int>Q; int inQ[maxn];
vector< pair<int, pair<unsigned int,int> > >G[maxn];
inline void citire () {
fscanf(f,"%d %d %d",&k,&n,&m);
for ( int i = 1 ; i <= k ; ++i ){
fscanf(f,"%d",&where[i]);
which[where[i]] = i;
}
int x,y; unsigned int cost,lim;
for ( int i = 1 ; i <= m ; ++i ){
fscanf(f,"%d %d %d %d",&x,&y,&cost,&lim);
if ( lim > 20 ) lim = 20;
G[x].pb(mp(y,mp(cost,lim)));
G[y].pb(mp(x,mp(cost,lim)));
}
}
inline void bf ( int start , int nr , long long *dist ){
for ( int i = 1 ; i <= n ; ++i ){
dist[i] = inf;
T[i] = 0;
}
dist[start] = 0;
Q.push(start); inQ[start] = 1;
while ( !Q.empty() ){
int nod = Q.front(); Q.pop(); inQ[nod] = 0;
if ( inQ[ T[nod] ] ) continue ;
for ( vector< pair<int, pair<unsigned int,int> > >::iterator itt = G[nod].begin() ; itt != G[nod].end() ; ++itt ){
int vecin = itt->first;
unsigned int cost = itt->second.first;
int lim_here = itt->second.second;
if ( lim_here >= nr ){
if ( dist[vecin] > dist[nod] + 1LL*cost*(nr+1) ){
dist[vecin] = dist[nod] + 1LL*cost*(nr+1);
T[vecin] = nod;
if ( !inQ[vecin] ){
Q.push(vecin); inQ[vecin] = 1;
}
}
}
}
}
}
inline void get_shortest () {
for ( int i = 1 ; i <= k ; ++i ){
for ( int nr = 0 ; nr <= k ; ++nr ){
bf(where[i],nr,D[i][nr]);
}
}
bf(1,0,D[0][0]);
}
inline void compute_biti () {
for ( int i = 1 ; i < (1<<k) ; ++i ){
int conf = i;
while ( conf ){
++biti[i];
conf &= (conf-1);
}
}
}
inline void solve () {
for ( int i = 1 ; i <= k ; ++i ){
for ( int j = 0 ; j < (1<<k) ; ++j ){
best[i][j] = inf;
}
}
compute_biti();
best[0][0] = 0;
for ( int conf = 0 ; conf < (1<<k) ; ++conf ){
for ( int nod = (conf != 0) ; nod <= k ; ++nod ){
for ( int next = 1 ; next <= k ; ++next ){
int next_conf = conf;
if ( nod ){
next_conf |= (1<<(nod-1));
}
if ( best[next][next_conf] > best[nod][conf] + D[nod][ biti[next_conf] ][where[next]] ){
best[next][next_conf] = best[nod][conf] + D[nod][ biti[next_conf] ][where[next]];
}
}
}
}
long long sol = inf;
for ( int nod = 1 ; nod <= k ; ++nod ){
if ( best[nod][(1<<k)-1] < sol ){
sol = best[nod][(1<<k)-1];
}
}
fprintf(g,"%lld\n",sol);
}
int main () {
citire();
get_shortest();
solve();
fclose(f);
fclose(g);
return 0;
}