Pagini recente » Cod sursa (job #2373337) | Cod sursa (job #3210657) | Cod sursa (job #2612774) | Cod sursa (job #458116) | Cod sursa (job #1003781)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int NMAX = 755, INF = 0x3f3f3f3f, CONFMAX = (1 << 17), KMAX = 17;
int N, M, K, A, B, C, D, Special[KMAX], Min[NMAX][NMAX], Dist[NMAX][NMAX], Dp[CONFMAX][KMAX], Bit[CONFMAX];
vector<pair<int, int> > G[NMAX];
bool InQueue[NMAX];
void GetMin(int StartNode, int V[NMAX])
{
V[StartNode] = INF;
queue<int> Q;
Q.push(StartNode);
while(!Q.empty())
{
int Node = Q.front();
Q.pop();
InQueue[Node] = 0;
for(vector<pair<int, int> > :: iterator it = G[Node].begin(); it != G[Node].end(); ++ it)
if(min(V[Node], it -> second) > V[it -> first])
{
V[it -> first] = min(V[Node], it -> second);
if(!InQueue[it -> first])
Q.push(it -> first), InQueue[it -> first] = 1;
}
}
}
void GetMinDist()
{
for(int k = 1; k <= N; ++ k)
for(int i = 1; i <= N; ++ i)
for(int j = 1; j <= N; ++ j)
if(i != j)
Dist[i][j] = min(Dist[i][j], Dist[i][k] + Dist[k][j]);
for(int i = 1; i <= N; ++ i)
Dist[i][i] = 0;
}
void Build_B()
{
for(int i = 1; i < CONFMAX; ++ i)
Bit[i] = Bit[i >> 1] + (i & 1);
}
int GetAns()
{
Special[0] = 1;
memset(Dp, INF, sizeof(Dp));
Dp[1][0] = 0;
for(int Conf = 1; Conf < (1 << (K + 1)); ++ Conf)
for(int i = 0; i <= K; ++ i)
if(Dp[Conf][i] != INF)
for(int j = 0; j <= K; ++ j)
if(!(Conf & (1 << j)) && Min[Special[i]][Special[j]] + 1 >= Bit[Conf] && Dp[Conf ^ (1 << j)][j] > Dp[Conf][i] + Bit[Conf] * Dist[Special[i]][Special[j]])
Dp[Conf ^ (1 << j)][j] = Dp[Conf][i] + Bit[Conf] * Dist[Special[i]][Special[j]];
int Ans = INF;
for(int i = 0; i <= K; ++ i)
Ans = min(Ans, Dp[(1 << (K + 1)) - 1][i]);
return Ans;
}
int main()
{
freopen("gather.in", "r", stdin);
freopen("gather.out", "w", stdout);
scanf("%i %i %i", &K, &N, &M);
for(int i = 1; i <= K; ++ i)
scanf("%i", &Special[i]);
for(int i = 1; i <= N; ++ i)
for(int j = 1; j <= N; ++ j)
Dist[i][j] = INF;
for(int i = 1; i <= M; ++ i)
{
scanf("%i %i %i %i", &A, &B, &C, &D);
Dist[A][B] = Dist[B][A] = C;
G[A].push_back(make_pair(B, D));
G[B].push_back(make_pair(A, D));
}
for(int i = 1; i <= N; ++ i)
GetMin(i, Min[i]);
GetMinDist();
Build_B();
printf("%i\n", GetAns());
return 0;
}