Pagini recente » Cod sursa (job #1868960) | Cod sursa (job #1331533) | Cod sursa (job #1239734) | Cod sursa (job #1300478) | Cod sursa (job #923140)
Cod sursa(job #923140)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std ;
#define maxn ( 1 << 10 )
#define maxk ( 1 << 4 )
#define maxstari ( 1 << 16 )
#define inf ( 1 << 31 )
vector<int> graf[maxn] ;
int celule[maxk] ;
int dist[maxn] ;
int grafc[maxn][maxn] ;
int grafd[maxn][maxn] ;
int cost[maxk][maxk][maxk] ;
int din[maxstari][maxk] ;
int n, m, k ;
int num ;
bool cmp(const int &a, const int &b)
{
return dist[a] > dist[b] ;
}
void dijkstra(int nod, int num)
{
int heap[maxn] ;
for(int i = 1; i <= n; ++i )
dist[i] = inf ;
memset( heap, 0, sizeof( heap ) ) ;
heap[0] = 1 ;
heap[1] = nod ;
dist[nod] = 0 ;
while( heap[0] )
{
nod = heap[1] ;
pop_heap( heap + 1, heap + heap[0] + 1, cmp ) ;
--heap[0] ;
for(size_t i = 0; i < graf[nod].size(); ++i )
{
int nod_act = graf[nod][i] ;
if( dist[nod_act] > dist[nod] + ( num + 1 ) * grafc[nod][nod_act] && num <= grafd[nod][nod_act] )
{
dist[nod_act] = dist[nod] + ( num + 1 ) * grafc[nod][nod_act] ;
heap[ ++heap[0] ] = nod_act ;
push_heap( heap + 1, heap + heap[0] + 1, cmp ) ;
}
}
}
}
void citire()
{
scanf("%d%d%d", &k, &n, &m);
celule[0] = 1 ;
for(int i = 1; i <= k; ++i )
scanf("%d", &celule[i]);
while( m-- )
{
int x, y ;
scanf("%d%d", &x, &y);
scanf("%d%d", &grafc[x][y], &grafd[x][y]);
grafc[y][x] = grafc[x][y] ;
grafd[y][x] = grafd[x][y] ;
graf[x].push_back( y ) ;
graf[y].push_back( x ) ;
}
}
void init_dinamica(int limstari)
{
for(int i = 0; i < limstari; ++i )
for(int j = 0; j <= k; ++j )
din[i][j] = inf ;
}
void init_cost()
{
memset( cost, -1, sizeof( cost ) ) ;
for(int i = 0; i < k; ++i )
{
for(int j = 0; j <= k; ++j )
{
dijkstra( celule[j], i ) ;
for(int u = 1; u <= k; ++u )
if( dist[ celule[u] ] < inf )
cost[i][j][u] = dist[ celule[u] ] ;
}
}
}
void afla_num(int x)
{
while( x )
{
if( x & 1 )
++num ;
x >>= 1 ;
}
}
void rezolva_dinamica(int limstari)
{
din[0][0] = 0 ;
for(int stare = 0; stare < limstari; ++stare )
{
num = 0;
afla_num( stare ) ;
for(int nod = 0; nod <= k; ++nod )
if( din[stare][nod] < inf )
for(int i = 1; i <= k; ++i )
if( ( stare & ( 1 << ( i - 1 ) ) ) == 0 && din[ stare + ( 1 << ( i - 1 ) ) ][i] > din[stare][nod] + cost[num][nod][i] && cost[num][nod][i] >= 0 )
din[ stare + ( 1 << ( i - 1 ) ) ][i] = din[stare][nod] + cost[num][nod][i] ;
}
}
void afisare_sol(int stare)
{
int sol = inf ;
for(int i = 1; i <= k; ++i )
sol = min( sol, din[stare][i] ) ;
printf("%d\n", sol);
}
int main()
{
freopen("gather.in", "r", stdin);
freopen("gather.out", "w", stdout);
citire() ;
init_cost() ;
int limstari = ( 1 << k ) ;
init_dinamica( limstari ) ;
rezolva_dinamica( limstari ) ;
afisare_sol( limstari - 1 ) ;
return 0 ;
}