Pagini recente » Cod sursa (job #504582) | Cod sursa (job #112207) | Cod sursa (job #1725591)
#include <fstream>
#include <cstring>
#include <cassert>
using namespace std;
constexpr int MAX_N = 500;
constexpr int MAX_P = 50;
constexpr int MAX_M = 100001;
constexpr int INF = 0x3f3f3f3f;
constexpr int NIL = -1;
struct Edge {
int v, cost;
int next;
} G[2 * MAX_M];
int head[MAX_N];
void addEdge(const int u,
const int v,
const int weight,
const int pos) {
G[pos].v = v;
G[pos].cost = weight;
G[pos].next = head[u];
head[u] = pos;
}
int residence[MAX_P + 1];
int dp[MAX_P][MAX_P][MAX_P + 1];
int bfQ[1 << 9];
int bfWeight[MAX_P + 1][MAX_N];
bool inQueue[MAX_N];
void bFord(const int node,
const int n,
int weight[]) {
memset(weight, 0x3f, 4 * n);
weight[node] = 0;
int qStart = 0, qEnd = 1;
bfQ[0] = node;
while (qStart != qEnd) {
const int u = bfQ[(qStart++) & 511];
inQueue[u] = false;
for (int i = head[u]; i != NIL; i = G[i].next) {
const int v = G[i].v;
if (weight[v] > weight[u] + G[i].cost) {
weight[v] = weight[u] + G[i].cost;
if (not(inQueue[v])) {
bfQ[(qEnd++) & 511] = v;
inQueue[v] = true;
}
}
}
}
}
int main() {
ifstream fin("team.in");
ofstream fout("team.out");
fin.tie(0);
ios_base::sync_with_stdio(false);
int p, n, e; fin >> p >> n >> e;
memset(head, NIL, 4 * n);
for (int i = 0; i < e; i += 1) {
int node_1, node_2, weight; fin >> node_1 >> node_2 >> weight;
addEdge(node_1 - 1,
node_2 - 1,
weight,
2 * i);
addEdge(node_2 - 1,
node_1 - 1,
weight,
2 * i + 1);
}
for (int i = 0; i <= p; i += 1) {
if (i) {
fin >> residence[i]; residence[i] -= 1;
}
bFord(residence[i],
n,
bfWeight[i]);
}
for (int i = 0; i < p; i += 1) {
for (int k = 0; k <= p; k += 1) {
dp[i][i][k] = bfWeight[i + 1][residence[k]];
}
for (int j = i + 1; j < p; j += 1) {
for (int k = 0; k <= p; k += 1) {
dp[i][j][k] = INF;
}
}
}
for (int st = p - 2; st >= 0; st -= 1) {
for (int dr = st + 1; dr < p; dr += 1) {
for (int node = 0; node <= p; node += 1) {
int x = INF;
for (int split = st; split <= dr; split += 1) {
const int option = dp[st][split - 1][split + 1]
+ bfWeight[node][residence[split + 1]]
+ dp[split + 1][dr][split + 1];
if (option < x) {
x = option;
}
}
dp[st][dr][node] = x;
}
}
}
fout << dp[0][p - 1][0] << '\n';
fout.close();
return 0;
}