Pagini recente » Cod sursa (job #825912) | Cod sursa (job #236344) | Cod sursa (job #1073635) | Cod sursa (job #2802324) | Cod sursa (job #116974)
Cod sursa(job #116974)
#include <cstdio>
#include <vector>
using namespace std;
#define fin "gather.in"
#define fout "gather.out"
#define sz(x) (int)((x).size())
#define pb push_back
#define DxBG
#define FL
const int Nmax = 1000;
const unsigned int MAX = ( ( 1 << 32 ) - 1);
int N,M,K;
vector <int> g[Nmax],c[Nmax],d[Nmax];
vector <int> detinut;
unsigned int minc[Nmax],dist[16][16][16];
unsigned int dp[15][1<<15];
int nrb[1<<16];
int dim,heap[Nmax];
int poz[Nmax];
void readdata()
{
int i,x,y,cost,capac;
freopen(fin,"r",stdin);
scanf("%d%d%d",&K,&N,&M);
for (i=1;i<=K;++i)
{
scanf("%d",&x);
detinut.pb(x);
}
for ( i = 1 ; i <= M ; ++i )
{
scanf("%d%d",&x,&y);
scanf("%d%d",&cost,&capac);
g[x].pb(y); c[x].pb(cost); d[x].pb(capac);
g[y].pb(x); c[y].pb(cost); d[y].pb(capac);
}
}
void reconst_heap(int p)
{
int minim;
if ( minc[ heap[2*p] ] < minc[ heap[2*p+1] ])
minim = 2 * p;
else
minim = 2 * p + 1;
if ( minc[ heap[p] ] > minc[ heap[minim] ] && minim <= dim )
{
swap( poz[ heap[p] ] , poz[ heap[minim] ] );
swap( heap[ p ] , heap[ minim ] );
reconst_heap(minim);
}
}
void urca(int p)
{
if ( p / 2 >= 1 && minc[ heap[p] ] < minc[ heap[p/2] ] )
{
swap( heap[p] , heap[p/2] );
swap( poz[ heap[p] ] , poz[ heap[p/2] ] );
urca( p/2 );
}
}
void dijkstra(int sursa,int nrdet)
{
int i,x;
for ( i = 1 ; i <= N ; ++i )
{
minc[i]=MAX;
poz[i] = 0;
}
minc[sursa] = 0;
poz[sursa] = 1;
heap[1] = sursa;
dim = 1 ;
while ( dim > 0 )
{
x = heap[1];
heap[1] = heap[dim];
--dim;
reconst_heap(1);
for ( i = 0 ; i < sz(g[x]); ++i )
{
if ( nrdet <= d[x][i] && ( minc[x] + c[x][i] < minc[ g[x][i] ] || poz[ g[x][i] ] == 0 ) )
{
minc[ g[x][i] ] = minc[x] + c[x][i];
if ( poz[ g[x][i] ] == 0 )
{
++dim;
poz[ g[x][i] ] = dim;
heap[dim] = g[x][i];
urca( dim );
}
else
urca( poz[ g[x][i] ] );
}
}
}
}
void solve()
{
int i,j,k;
unsigned int ret;
for ( i = 0; i < sz(detinut) ; ++i )
for ( j = 1; j <= K ; ++j )
{
dijkstra(detinut[i],j);
for ( k = 0 ; k < sz(detinut); ++k)
dist[ i ][ k ][ j ] = minc[ detinut[k] ];
#ifdef DBG
printf("%d %d\n",detinut[i],j);
for ( k = 0 ; k < sz(detinut) ; ++k )
printf("%u ",dist[i][k][j]);
printf("\n\n");
#endif
}
dijkstra(1,0);
for ( i = 0 ; i < sz(detinut) ; ++i )
for ( j = 0 ; j < ( 1 << K ) ; ++j )
dp[i][j] = MAX;
for ( i = 0 ; i < sz(detinut) ; ++i )
dp[i][1<<i] = minc[ detinut[i] ];
for ( i = 0 ; i < ( 1 << K ) ; ++i )
{
for ( j = 0 ; ( 1 << j ) <= i ; ++j )
if ( ( 1 << j ) & i )
++nrb[i];
}
for ( k = 0 ; k < ( 1 << K ) ; ++k )
{
for ( i = 0 ; i < sz(detinut) ; ++i )
if ( ( k & ( 1 << i ) ) == 0 )
{
for ( j = 0 ; j < sz(detinut) ; ++j )
if ( ( k & ( 1 << j ) ) && dist[i][j][nrb[k]] < MAX )
dp[i][k | ( 1 << i ) ] = min( dp[i][k | ( 1 << i ) ] , (nrb[k]+1)*dist[i][j][nrb[k]] + dp[j][k]);
}
}
ret = dp[0][(1<<K)-1];
for ( i = 0 ; i < sz(detinut) ; ++i )
ret = min( ret , dp[i][(1<<K)-1] );
#ifdef DBG
for ( i = 0 ; i < sz(detinut) ; ++i )
{
for ( j = 0 ; j < ( 1 << K ) ; ++j )
if ( dp[i][j] < MAX ) printf("%u ",dp[i][j]);
else
printf("0 ");
printf("\n");
}
#endif
#ifdef FL
freopen(fout,"w",stdout);
#endif
printf("%u\n",ret);
}
int main()
{
readdata();
solve();
return 0;
}