Pagini recente » Cod sursa (job #1902002) | Cod sursa (job #1728169) | Cod sursa (job #3183584) | Cod sursa (job #1135168) | Cod sursa (job #2538833)
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const long long INF = 10000000000000000;
const int NRMAX = 1 << 17;
const int NMAX = 755;
const int KMAX = 18;
long long cost[KMAX][NMAX][NMAX];
int a[NMAX];
struct Muchie {
int x;
long long c;
int d;
};
vector <Muchie> vec[NMAX];
struct Dikjstra {
int x;
long long c;
};
bool operator < (Dikjstra first, Dikjstra second) {
return (first.c < second.c);
}
priority_queue <Dikjstra> pq;
long long dp[NRMAX];
int b[KMAX];
void F(int nod, int d) {
pq.push({nod, 0});
cost[d][nod][nod] = 0;
while(!pq.empty()) {
auto p = pq.top();
pq.pop();
if(cost[d][nod][p.x] == p.c) {
for(auto u : vec[p.x]) {
if(u.d >= d) {
if(cost[d][nod][u.x] > p.c + u.c) {
cost[d][nod][u.x] = p.c + (u.c * (d + 1));
pq.push({u.x, p.c + u.c});
}
}
}
}
}
}
int main() {
int k, n, m;
freopen("gather.in", "r", stdin);
freopen("gather.out", "w", stdout);
scanf("%d%d%d", &k, &n, &m);
for(int i = 0; i < k; i++) {
scanf("%d", &a[i]);
}
for(int i = 1; i <= m; i++) {
int x, y, d;
long long c;
scanf("%d%d%lld%d", &x, &y, &c, &d);
vec[x].push_back({y, c, d});
vec[y].push_back({x, c, d});
}
for(int d = 0; d <= k; d++) {
for(int i = 0; i < k; i++) {
for(int j = 1; j <= n; j++) {
cost[d][a[i]][j] = INF;
}
}
for(int j = 2; j <= n; j++) {
cost[d][1][j] = INF;
}
F(1, d);
for(int i = 0; d > 0 && i < k; i++) {
F(a[i], d);
}
}
for(int mask = 1; mask < (1 << k); mask++) {
dp[mask] = INF;
}
for(int i = 0; i < k; i++) {
dp[1 << i] = cost[0][1][a[i]];
}
for(int mask = 1; mask < (1 << k) - 1; mask++) {
int cmask = mask, top = 0;
while(mask > 0) {
b[top++] = mask % 2;
mask /= 2;
}
mask = cmask;
int nr1 = 0;
for(int i = 0; i < top; i++) {
nr1 += b[i];
}
for(int i = 0; i < top; i++) {
if(b[i] == 1) {
for(int j = 0; j < k; j++) {
if(b[j] == 0) {
long long c = dp[mask] + cost[nr1][a[i]][a[j]];
dp[mask | (1 << j)] = min(dp[mask | (1 << j)], c);
}
}
}
}
}
printf("%lld\n", dp[(1 << k) - 1]);
return 0;
}