Pagini recente » Cod sursa (job #522968) | Cod sursa (job #1738650) | Cod sursa (job #290506) | Cod sursa (job #581690) | Cod sursa (job #961050)
Cod sursa(job #961050)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
ifstream in ("gather.in");
ofstream out ("gather.out");
const int MAXN = 755;
const int MAXK = 16;
const int INF = 0x3f3f3f3f;
struct triple
{
int x, y, z;
};
int N;
vector <triple> Graf[MAXN];
int V[MAXK];
int A[MAXK][1 << MAXK], D[MAXK][MAXK][MAXN];
//A[i][j] = costul minim de a ajunge in nodul j, cu detinutii marcati cu 1 in reprezentarea binara a lui i
//D[i][j][k] = costul minim de a ajunge in nodul k, plecand din i si trecand prin muchii cu capacitatea >= j
priority_queue < pair < int, int> > Q;
void Dijkstra (int S, int lim, int Best[])
{
int nod, d;
for (nod = 0; nod <= N; nod ++)
Best[nod] = INF;
Best[S] = 0;
Q.push (make_pair (0, S));
while (!Q.empty ()){
nod = Q.top ().second;
d = -Q.top ().first;
Q.pop ();
if (Best[nod] < d)
continue;
for (auto it : Graf[nod]){
if (it.z < lim)
continue;
if (Best[nod] + it.y < Best[it.x]){
Best[it.x] = Best[nod] + it.y;
Q.push (make_pair (-Best[it.x], it.x));
}
}
}
}
inline int nrbiti (int X)
{
int ret = 0;
while (X) ret ++, X &= X - 1;
return ret;
}
int main()
{
int M, K, i, j, k, nod1, nod2, cap, lung, now;
in >> K >> N >> M;
for (i = 1; i <= K; i ++)
in >> V[i], -- V[i];
while (M --){
in >> nod1 >> nod2 >> lung >> cap;
-- nod1, -- nod2;
Graf[nod1].push_back ({nod2, lung, cap});
Graf[nod2].push_back ({nod1, lung, cap});
}
for (i = 0; i <= K + 1; i ++)
for (j = 0; j <= K + 1 ; j ++)
Dijkstra (V[i], j, D[i][j]);
memset (A, 0x3f, sizeof (A));
A[1][0] = 0;
for (i = 2; i < (1 << (K + 1)); i ++){
now = nrbiti (i) - 2;
for (j = 0; j <= K; j ++)
if (i & (1 << j))
for (k = 0; k <= K; k ++)
if (A[i ^ (1 << j)][k] != INF && D[k][now <= 0 ? now : 0][V[j]] != INF)
A[i][j] = min (A[i][j], A[i ^ (1 << j)][k] + (now + 1) * D[k][now <= 0 ? now : 0][V[j]]);
}
int Ans = INF;
for (i = 1; i <= K; i ++)
Ans = min (Ans, A[(1 << (K + 1)) - 1][i]);
out << Ans;
return 0;
}