Pagini recente » Cod sursa (job #1393306) | Cod sursa (job #2420629) | Cod sursa (job #488983)
Cod sursa(job #488983)
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#define MAX 1500
#define ll long long
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define INF 1000000000000000000LL
using namespace std;
ll k, n, m, dimHeap, nrDet;
ll vctDist[MAX], det[MAX];
vector <pair <pair <ll, ll>, ll> > vctDrum[MAX];
ll sol[65000][17];
ll dist[32][32][32];
priority_queue <pair <ll, int> > minHeap;
inline void dijkstra(int source)
{
dimHeap = n;
for (int i = 1; i <= n; i++)
vctDist[i] = INF;
vctDist[source] = 0;
minHeap.push(mp(0, source));
for (; minHeap.size(); )
if (minHeap.top().f == vctDist[minHeap.top().s])
{
int nod = minHeap.top().s;
minHeap.pop();
if (vctDist[nod] == INF)
return;
for (int i = 0; i < vctDrum[nod].size(); i++)
if (vctDrum[nod][i].s >= nrDet && vctDist[nod] + vctDrum[nod][i].f.s < vctDist[vctDrum[nod][i].f.f])
{
vctDist[vctDrum[nod][i].f.f] = vctDist[nod] + vctDrum[nod][i].f.s;
minHeap.push(mp(-vctDist[vctDrum[nod][i].f.f], vctDrum[nod][i].f.s));
}
}
else minHeap.pop();
}
int main()
{
freopen("gather.in", "r", stdin);
freopen("gather.out", "w", stdout);
scanf("%lld %lld %lld", &k, &n, &m);
for (int i = 0; i < k; i++)
scanf("%lld\n", &det[i]);
for (int i = 1; i <= m; i++)
{
ll n1, n2, c, d;
scanf("%lld %lld %lld %lld", &n1, &n2, &c, &d);
vctDrum[n1].pb(mp(mp(n2, c), d));
vctDrum[n2].pb(mp(mp(n1, c), d));
}
for (nrDet = k; nrDet; nrDet--)
for (int i = 0; i < k; i++)
{
dijkstra(det[i]);
for (int j = 0; j < k; j++)
dist[nrDet][i][j] = vctDist[det[j]];
}
dijkstra(1);
for (int i = 0; i < (1 << k); i++)
for (int j = 0; j < k; j++)
sol[i][j] = INF;
for (int i = 0; i < k; i++)
sol[1 << i][i] = vctDist[det[i]];
for (int conf = 1; conf < (1 << k); conf++)
for (int ult = 0; ult < k; ult++)
if (sol[conf][ult] != INF && (conf & (1 << ult)))
{
nrDet = 0;
for (int j = conf; j; nrDet++, j &= (j - 1));
for (int nou = 0; nou < k; nou++)
if (dist[nrDet][ult][nou] != INF && !(conf & (1 << nou)))
sol[conf | (1 << nou)][nou] = min(sol[conf | (1 << nou)][nou], sol[conf][ult] + (nrDet + 1) * dist[nrDet][ult][nou]);
}
ll minGs = INF;
for (int i = 0; i < k; i++)
minGs = min(minGs, sol[(1 << k) - 1][i]);
if (minGs == INF)
for (; ; );
printf("%lld\n", minGs);
fclose(stdin);
fclose(stdout);
return 0;
}