Pagini recente » Cod sursa (job #2907089) | Cod sursa (job #1510140) | Cod sursa (job #1201438) | Cod sursa (job #1231356) | Cod sursa (job #2766879)
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("gather.in");
ofstream fout("gather.out");
const int MAXK = 16;
const int MAXN = 750;
int d[MAXK];
vector<tuple<int,int,int>> G[MAXN];
int dp[MAXK][1 + MAXK][MAXN], a[MAXK][1 << MAXK];
/// dp[i][j][nod] - costul minim pentru a ajunge de la nodul in care se afla detinutul cu numarul i la nod
/// folosind doar muchii cu capacitatea >= j
/// a[i][mask] - costul minim pentru a aduce in celula detinutului i toti detinutii al caror bit este setat in mask
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;
void Dijkstra(int s, int low, int D[]) {
D[s] = 0;
pq.emplace(D[s], s);
while (!pq.empty()) {
int dist, u;
tie(dist, u) = pq.top();
pq.pop();
if (dist != D[u])
continue;
for (auto it : G[u]) {
int v, w, c;
tie(v, w, c) = it;
if (c >= low && D[v] > D[u] + w) {
D[v] = D[u] + w;
pq.emplace(D[v], v);
}
}
}
}
void min_self(int &x, int y) {
if (x > y)
x = y;
}
int main() {
int k, n, m;
fin >> k >> n >> m;
++k;
for (int i = 1; i < k; ++i) {
fin >> d[i];
--d[i];
}
for (int i = 0; i < m; ++i) {
int u, v, w, c;
fin >> u >> v >> w >> c;
--u, --v;
G[u].emplace_back(v, w, c);
G[v].emplace_back(u, w, c);
}
memset(dp, INF, sizeof dp);
for (int i = 0; i < k; ++i)
for (int j = 0; j <= k; ++j)
Dijkstra(d[i], j, dp[i][j]);
memset(a, INF, sizeof a);
a[0][1] = 0;
for (int mask = 2; mask < (1 << k); ++mask) {
int cnt_det = __builtin_popcount(mask) - 1; /// Gigel nu trebuie numarat(capacitatile muchiilor limiteaza numarul de prizonieri doar)
for (int i = 0; i < k; ++i)
if (mask & (1 << i)) {
int prev_mask = mask ^ (1 << i);
for (int j = 0; j < k; ++j) {
if (a[j][prev_mask] == INF || dp[j][cnt_det - 1][d[i]] == INF)
continue;
min_self(a[i][mask], a[j][prev_mask] + cnt_det * dp[j][cnt_det - 1][d[i]]); /// detinutul i nu trebuie numarat
}
}
}
int ans = INF;
for (int i = 0; i < k; ++i)
min_self(ans, a[i][(1 << k) - 1]);
fout << ans << '\n';
fin.close();
fout.close();
return 0;
}