Pagini recente » Cod sursa (job #26313) | Cod sursa (job #1315097) | Cod sursa (job #2614050) | Cod sursa (job #1415835) | Cod sursa (job #1518234)
#include <fstream>
using namespace std;
ifstream in("gather.in");
ofstream out("gather.out");
#define N 755
#define K 20
#define M 1255
#define INF (1 << 31) - 1
int n, m, k;
int lst[N], vf[2 * M], urm[2 * M], cost[2 * M], capacitate[2 * M], nr;
int h[N], poz[N], nh;
int d[N], b[K];
int cost2[K][K][K];
int a[1 << K][K];
int biti[1 << K];
void schimba(int i1, int i2)
{
int aux = h[i1];
h[i1] = h[i2];
h[i2] = aux;
poz[h[i1]] = i1;
poz[h[i2]] = i2;
}
void urca(int i)
{
while(i >= 2 && d[h[i]] < d[h[i / 2]])
{
schimba(i, i / 2);
i /= 2;
}
}
void coboara(int i)
{
int bun = i, fs = 2 * i, fd = 2 * i + 1;
if(fs <= nh && d[h[fs]] < d[h[bun]])
bun = fs;
if(fd <= nh && d[h[fd]] < d[h[bun]])
bun = fd;
if(bun != i)
{
schimba(i, bun);
coboara(bun);
}
}
void adauga(int x)
{
h[++nh] = x;
poz[x] = nh;
urca(nh);
}
void sterge(int i)
{
poz[h[i]] = 0;
schimba(i, nh);
nh--;
coboara(i);
}
void dijkstra(int x, int cap)
{
for(int i = 1; i <= n; i++)
{
d[i] = INF;
h[i] = 0;
poz[i] = 0;
}
nh = 0;
d[x] = 0;
adauga(x);
while(nh)
{
x = h[1];
sterge(1);
for(int i = lst[x]; i; i = urm[i])
{
if(capacitate[i] < cap)
continue;
int y, c;
y = vf[i];
c = cost[i];
if(d[x] + c < d[y])
{
d[y] = d[x] + c;
if(poz[y] == 0)
adauga(y);
else
urca(poz[y]);
}
}
}
}
int minim(int x, int y)
{
return x < y ? x : y;
}
int main()
{
in >> k >> n >> m;
b[0] = 1;
for(int i = 1; i <= k; i++)
in >> b[i];
k++;
for(int i = 1; i <= m; i++)
{
int x, y, c, cap;
in >> x >> y >> c >> cap;
vf[++nr] = y;
cost[nr] = c;
capacitate[nr] = cap;
urm[nr] = lst[x];
lst[x] = nr;
vf[++nr] = x;
cost[nr] = c;
capacitate[nr] = cap;
urm[nr] = lst[y];
lst[y] = nr;
}
for(int i = 0; i < k; i++)
for(int j = 0; j < k; j++)
{
dijkstra(b[i], j);
for(int p = 0; p < k; p++)
{
cost2[i][p][j] = INF;
if(b[i] != b[p] && d[b[p]] != INF)
cost2[i][p][j] = d[b[p]];
}
}
for(int i = 1; i <= (1 << k) - 1; i += 2)
{
int aux = i;
int nrb = 0;
while(aux)
{
nrb++;
aux &= aux - 1;
}
biti[i] = nrb;
}
for(int i = 1; i <= (1 << k) - 1; i += 2)
for(int j = 0; j < k; j++)
a[i][j] = INF;
a[1][0] = 0;
for(int i = 3; i <= (1 << k) - 1; i += 2)
for(int j = 1; j < k; j++)
{
if(!(i & (1 << j)))
continue;
for(int l = 0; l < k; l++)
if((i - (1 << j)) & (1 << l) && a[i - (1 << j)][l] != INF)
{
int capmin = biti[i] - 2;
for(int cap = capmin; cap < k; cap++)
if(cost2[l][j][cap] != INF)
a[i][j] = minim(a[i][j], a[i - (1 << j)][l] + cost2[l][j][cap] * (biti[i] - 1));
}
}
int rezminim = INF;
for(int i = 0; i < k; i++)
rezminim = minim(rezminim, a[(1 << k) - 1][i]);
out << rezminim << '\n';
return 0;
}