Pagini recente » Cod sursa (job #282084) | Cod sursa (job #6798) | Cod sursa (job #2758340) | Cod sursa (job #3142574) | Cod sursa (job #2758353)
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("team.in");
ofstream fout("team.out");
const int MAXN = 500;
const int MAXP = 50;
vector<pair<int,int>> G[1 + MAXN];
int dist[1 + MAXP][1 + MAXN], dp[1 + MAXP][1 + MAXP][1 + MAXP];
/// dp[i][j][k] - costul minim pentru a aduce la destinatie persoanele din intervalul i...j, considerand ca acestea pleaca de la destinatia persoanei k
/// Cum pot ajunge la asta?
/// Observi ca daca duci o persoana la destinatia sa, grupul se imparte in doua, deci acea persoana e un split point, deci de aici te poti gandi la range dp(O(p^3) pana aici)
/// Nu sti in ce ordine sa parcurgi graful pentru a lasa persoane la destinatii si obtine si solutie optima, p e mic, deci mai poti adauga o stare la dinamica care sa zica din ce sediu vrei sa pleci mai departe cu un grup(pentru ca mereu ai nevoie de rezultatelee grupurilor mai mici pentru a calcula un grup mare se deduce usor ca dinamica trebuie calculata bottom-up(intervalele mai mici primele)) => O(p^4)
/// => Raspunsul este dp[0][p - 1][0](plec cu tot grupul din prima statie)
/// Obs: persoanele adiacente(adica cu indici consecutivi) care au aceeasi destinatie pot fi transformate intr-o singura persoana, pentru ca mereu va fi optim sa le las la destinatie pe toate in acelasi timp
void min_self(int &x, int y) {
x = min(x, y);
}
int main() {
int p, n, m;
fin >> p >> n >> m;
for (int i = 0; i < m; ++i) {
int u, v, w;
fin >> u >> v >> w;
G[u].emplace_back(v, w);
G[v].emplace_back(u, w);
}
vector<int> sources;
int k = 0;
for (int i = 0; i <= p; ++i) {
int nod;
if (i == 0)
nod = 1;
else fin >> nod;
if (sources.empty() || nod != sources.back()) {
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
for (int v = 1; v <= n; ++v)
dist[k][v] = INF;
dist[k][nod] = 0;
pq.emplace(0, nod);
while (0 < pq.size()) {
int d, u;
tie(d, u) = pq.top();
pq.pop();
if (d != dist[k][u])
continue;
for (auto it : G[u]) {
int v, w;
tie(v, w) = it;
int cost = d + w;
if (dist[k][v] > cost) {
dist[k][v] = cost;
pq.emplace(dist[k][v], v);
}
}
}
sources.emplace_back(nod);
k = sources.size();
}
}
p = k;
for (int i = 0; i < p; ++i)
for (int j = i; j < p; ++j)
for (int k = 0; k < p; ++k)
dp[i][j][k] = INF;
for (int lg = 1; lg <= p; ++lg)
for (int i = 0; i + lg - 1 < p; ++i) {
int j = i + lg - 1;
for (int k = i; k <= j; ++k)
for (int t = 0; t < p; ++t) {
int best = dist[t][sources[k]];
if (i <= k - 1)
best += dp[i][k - 1][k];
if (k + 1 <= j)
best += dp[k + 1][j][k];
min_self(dp[i][j][t], best);
}
}
fout << dp[0][p - 1][0] << '\n';
fin.close();
fout.close();
return 0;
}