Pagini recente » Cod sursa (job #2395851) | Cod sursa (job #322193) | Cod sursa (job #2120421) | Cod sursa (job #1952993) | Cod sursa (job #2538808)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 750;
const int MAXK = 16;
const int MAXM = 1250;
struct Edge {
int u;
long long c, d;
bool operator <(const Edge& other) const {
return c > other.c;
}
};
struct Node {
int node;
long long c;
bool operator <(const Node& other) const {
return c > other.c;
}
};
vector<Edge>G[MAXN + 5];
int det[MAXK + 5];
long long dist[MAXK + 5][MAXK + 5][MAXK + 5];
long long dd[MAXN + 5];
long long dp[(1 << MAXK) + 5][MAXK + 5];
int main() {
freopen("gather.in", "r", stdin);
freopen("gather.out", "w", stdout);
int n, m, k;
scanf("%d%d%d", &k, &n, &m);
for (int i = 1; i <= k; ++i)
scanf("%d", &det[i]);
for (int i = 1; i <= m; ++i) {
int u, v;
long long c, d;
scanf("%d%d", &u, &v);
scanf("%lld%lld", &d, &c);
G[u].push_back({v, c, d});
G[v].push_back({u, c, d});
}
for (int i = 1; i <= n; ++i)
sort(G[i].begin(), G[i].end());
det[0] = 1;
for (int cat = 0; cat <= k; ++cat) {
for (int d = 0; d <= k; ++d) {
memset(dd, -1, sizeof(dd));
priority_queue<Node>pq;
pq.push({det[d], 0});
while (!pq.empty()) {
Node aux = pq.top();
pq.pop();
if (dd[aux.node] != -1)
continue;
dd[aux.node] = aux.c;
for (auto it:G[aux.node]) {
if (it.c < cat)
break;
if (dd[it.u] == -1 || 1LL * it.d * (cat + 1) + aux.c <= (1LL << 32))
pq.push({it.u, 1LL * it.d * (cat + 1) + aux.c});
}
}
for (int x = 0; x <= k; ++x)
dist[cat][d][x] = dd[det[x]];
}
}
memset(dp, -1, sizeof(dp));
dp[0][0] = 0;
k++;
for (int s = 0; s < (1 << k); ++s) {
int nb = 0;
for (int i = 0; i < k; ++i)
if (s & (1 << i))
nb++;
for (int i = 0; i < k; ++i)
if (dp[s][i] != -1) {
for (int j = 1; j < k; ++j) {
if (s & (1 << j))
continue;
if (dp[s ^ (1 << j)][j] == -1 && dist[nb][i][j] != -1)
dp[s ^ (1 << j)][j] = dp[s][i] + dist[nb][i][j];
else if (dp[s ^ (1 << j)][j] != -1 && dist[nb][i][j] != -1)
dp[s ^ (1 << j)][j] = min(dp[s ^ (1 << j)][j], dp[s][i] + dist[nb][i][j]);
}
}
}
long long ans = (1LL << 60);
for (int i = 1; i <= k; ++i)
if (dp[(1 << k) - 2][i] != -1)
ans = min(ans, dp[(1 << k) - 2][i]);
printf("%lld\n", ans);
return 0;
}