Pagini recente » Cod sursa (job #2957034) | Cod sursa (job #2724332) | Cod sursa (job #3037737) | Cod sursa (job #3173362) | Cod sursa (job #1743596)
#include <fstream>
#include <algorithm>
#include <vector>
#include <limits>
#include <cstring>
#include <queue>
using namespace std;
ifstream cin("gather.in");
ofstream cout("gather.out");
const int MAXN = 750;
const int MAXK = 15;
const long long INFLL = numeric_limits<long long>::max();
int k, n, m;
int which[MAXK], index[1 + MAXN];
long long dp[1 + MAXK][1 << MAXK], step[1 + MAXK][1 + MAXK][1 + MAXK];
struct Edge{
int node;
int cost;
int people;
Edge(int _node, int _cost, int _people):
node(_node),
cost(_cost),
people(_people) {}
};
vector<Edge> g[1 + MAXN];
int BitCount(int mask) {
int answer = 0;
while (mask) {
mask -= (mask & -mask);
answer++;
}
return answer;
}
bool inQueue[1 + MAXN];
long long best[1 + MAXN];
queue<int> Queue;
void Solve() {
memset(dp, 0x3f3f3f3f, sizeof(dp));
for (int people = 0; people <= k; people++)
for (int start = 1; start <= k + 1; start++)
if (start != k + 1 || people == 0) {
memset(inQueue, false, sizeof(inQueue));
memset(best, 0x3f3f3f3f, sizeof(best));
if (start == k + 1) {
Queue.push(1);
inQueue[1] = true;
best[1] = 0;
}
else {
Queue.push(which[start - 1]);
inQueue[which[start - 1]] = true;
best[which[start - 1]] = 0;
}
while (!Queue.empty()) {
int node = Queue.front();
Queue.pop();
inQueue[node] = false;
for (auto &edge : g[node])
if (edge.people >= people)
if (best[edge.node] > best[node] + edge.cost * (people + 1)) {
best[edge.node] = best[node] + edge.cost * (people + 1);
if (!inQueue[edge.node]) {
Queue.push(edge.node);
inQueue[edge.node] = true;
}
}
}
if (start == k + 1)
for (int j = 1; j <= k; j++)
dp[j][0] = best[which[j - 1]];
else
for (int j = 1; j <= k; j++)
step[people][start][j] = best[which[j - 1]];
}
for (int mask = 0; mask < (1 << k); mask++)
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
if (!(mask & (1 << (j - 1))))
dp[j][mask | (1 << (j - 1))] = min(dp[j][mask | (1 << (j - 1))], dp[i][mask] + step[BitCount(mask)][i][j]);
}
int main() {
cin >> k >> n >> m;
for (int i = 1; i <= n; i++)
index[i] = -1;
for (int i = 0; i < k; i++) {
cin >> which[i];
index[which[i]] = i;
}
for (int i = 1; i <= m; i++) {
int a, b, c, d;
cin >> a >> b >> c >> d;
g[a].push_back(Edge(b, c, d));
g[b].push_back(Edge(a, c, d));
}
Solve();
long long answer = INFLL;
for (int i = 1; i <= k; i++)
answer = min(answer, dp[i][(1 << k) - 1]);
cout << answer << "\n";
return 0;
}