Pagini recente » Cod sursa (job #1636291) | Cod sursa (job #1241375) | Cod sursa (job #2852619) | Cod sursa (job #3198949) | Cod sursa (job #1522511)
#include <cstdio>
#include <queue>
#include <algorithm>
using std::min;
const int MAX_K = 15 + 1;
const int MAX_N = 750;
const int MAX_M = 1250;
const int NIL = -1;
const long long INF = 0x3F3F3F3F3F3F3F3FLL;
struct Edge {
int v, cost;
int cap, next;
};
/* datele citite */
Edge l[2 * MAX_M];
int adj[MAX_N];
int p[MAX_K];
int n;
/* pentru SPFA */
long long d[MAX_N];
bool inQueue[MAX_N];
std::queue <int> q;
/* pentru Hamilton */
long long DP[MAX_K][MAX_K][MAX_N];
int popCount[1 << MAX_K];
long long H[1 << MAX_K][MAX_K];
int k;
void addEdge(int u, int v, int cost, int capacity, int pos) {
l[pos].v = v;
l[pos].cost = cost;
l[pos].cap = capacity;
l[pos].next = adj[u];
adj[u] = pos;
}
void spfa(int u, int minCap) {
for (int i = 0; i < n; i++) {
d[i] = INF;
}
q.push(u);
d[u] = 0;
while (!q.empty()) {
u = q.front();
q.pop();
inQueue[u] = 0;
for (int i = adj[u]; i != NIL; i = l[i].next) {
if (l[i].cap >= minCap) {
int v = l[i].v;
int cost = d[u] + l[i].cost;
if (d[v] > cost) {
d[v] = cost;
if (!inQueue[v]) {
inQueue[v] = 1;
q.push(v);
}
}
}
}
}
}
long long go(int mask, int node) {
if (H[mask][node]) {
return H[mask][node];
}
long long q = INF;
if (mask == (1 << k) - 1) {
q = 0LL;
} else {
for (int i = 0; i < k; i++) {
if (!((mask >> i) & 1)) {
q = min(q, go(mask ^ (1 << i), i) + 1LL * popCount[mask] * DP[node][ popCount[mask] ][ p[i] ]);
}
}
}
return H[mask][node] = q;
}
int main(void) {
freopen("gather.in", "r", stdin);
freopen("gather.out", "w", stdout);
int m;
int u, v, cost, capacity;
scanf("%d%d%d", &k, &n, &m);
p[0] = 0;
for (int i = 1; i <= k; i++) {
scanf("%d", &p[i]);
p[i]--;
}
k++;
for (int i = 0; i < n; i++) {
adj[i] = NIL;
}
for (int i = 0; i < m; i++) {
scanf("%d%d%d%d", &u, &v, &cost, &capacity);
addEdge(u - 1, v - 1, cost, capacity + 1, 2 * i);
addEdge(v - 1, u - 1, cost, capacity + 1, 2 * i + 1);
}
fclose(stdin);
for (int i = 0; i < k; i++) {
for (int j = 1; j < k; j++) {
spfa(p[i], j);
for (u = 0; u < n; u++) {
DP[i][j][u] = d[u];
}
}
}
for (int i = 1; i < (1 << k); i++) {
popCount[i] = (i & 1) + popCount[i >> 1];
}
printf("%lld\n", go(1, 0));
fclose(stdout);
return 0;
}