This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
const int MAXN = 2005;
const int MAXM = 4005;
const int MAXL = 100005;
const lint INF = 1e18;
struct edge_t {
int u, v, w; // u = from, v = to, w = weight
edge_t() {}
edge_t(int u, int v, int w) : u(u), v(v), w(w) {}
};
int N, M, T, L;
namespace ShortestPath {
vector<edge_t> edges;
vector<int> adj[MAXN];
// Distance[X][Y][Use X?][Use Y?] = Shortest Path from edges[X].u to edges[Y].v that Use X? Use Y?
lint Distance[MAXM][MAXM][2][2];
int LastEdgeDistance[MAXM][MAXM][2][2]; // last edge used in Distance[][][][]
// ShortestPathEdge[X][edges[Y].v][use X?] = Y that has the shortest distance
int ShortestPathEdge[MAXM][MAXN][2];
void Read() {
M = M * 2;
for (int i = 0; i < (M / 2); i++) {
int A, B, C;
cin >> A >> B >> C;
A--, B--;
adj[A].emplace_back(edges.size());
edges.emplace_back(A, B, C);
adj[B].emplace_back(edges.size());
edges.emplace_back(B, A, C);
}
}
void Dijkstra(int X) { // Finds all Distance[X][][1][1]
priority_queue<pair<lint, int>, vector<pair<lint, int>>, greater<pair<lint, int>>> pq;
pq.emplace(edges[X].w, X);
Distance[X][X][1][1] = edges[X].w; // from edges[X].u to edges[X].v
// Run Dijkstra to find Distance[X][][1][1].
// Make sure we do not do a U-turn.
while (!pq.empty()) {
int cur = pq.top().second;
lint cur_dist = pq.top().first;
pq.pop();
if (cur_dist != Distance[X][cur][1][1]) continue;
int u = edges[cur].v;
for (auto nxt : adj[u]) {
if (cur == (nxt ^ 1)) continue; // We cannot U-turn back
lint &nxt_dist = Distance[X][nxt][1][1];
if (nxt_dist == -1 || nxt_dist > cur_dist + edges[nxt].w) {
nxt_dist = cur_dist + edges[nxt].w;
pq.emplace(nxt_dist, nxt);
}
}
}
}
void Solve() { // Computes Distance[][][][] and ShortestPathEdge[][][]
memset(Distance, -1, sizeof(Distance));
memset(LastEdgeDistance, -1, sizeof(LastEdgeDistance));
memset(ShortestPathEdge, -1, sizeof(ShortestPathEdge));
// Computes Distance[][][1][1]
for (int X = 0; X < M; X++) {
Dijkstra(X);
for (int Y = 0; Y < M; Y++) {
if (Distance[X][Y][1][1] != -1) {
LastEdgeDistance[X][Y][1][1] = Y;
}
}
}
// Computes Distance[][][1][0]
for (int X = 0; X < M; X++) {
vector<multiset<pair<lint, int>>> VertexDist(N);
for (int Y = 0; Y < M; Y++) {
VertexDist[edges[Y].v].emplace(Distance[X][Y][1][1], LastEdgeDistance[X][Y][1][1]);
}
for (int Y = 0; Y < M; Y++) {
auto it = VertexDist[edges[Y].v].find({Distance[X][Y][1][1], LastEdgeDistance[X][Y][1][1]});
VertexDist[edges[Y].v].erase(it);
if (!VertexDist[edges[Y].v].empty()) {
Distance[X][Y][1][0] = begin(VertexDist[edges[Y].v])->first;
LastEdgeDistance[X][Y][1][0] = begin(VertexDist[edges[Y].v])->second;
}
VertexDist[edges[Y].v].emplace(Distance[X][Y][1][1], LastEdgeDistance[X][Y][1][1]);
}
}
// Computes Distance[][][0][1]
for (int Y = 0; Y < M; Y++) {
vector<multiset<lint>> VertexDist(N);
for (int X = 0; X < M; X++) {
VertexDist[edges[X].u].emplace(Distance[X][Y][1][1]);
}
for (int X = 0; X < M; X++) {
auto it = VertexDist[edges[X].u].find(Distance[X][Y][1][1]);
VertexDist[edges[X].u].erase(it);
if (!VertexDist[edges[X].u].empty()) {
Distance[X][Y][0][1] = *begin(VertexDist[edges[X].u]);
LastEdgeDistance[X][Y][0][1] = Y;
}
VertexDist[edges[X].u].emplace(Distance[X][Y][1][1]);
}
}
// Computes Distance[][][0][0]
for (int X = 0; X < M; X++) {
vector<multiset<pair<lint, int>>> VertexDist(N);
for (int Y = 0; Y < M; Y++) {
VertexDist[edges[Y].v].emplace(Distance[X][Y][0][1], LastEdgeDistance[X][Y][0][1]);
}
for (int Y = 0; Y < M; Y++) {
auto it = VertexDist[edges[Y].v].find({Distance[X][Y][0][1], LastEdgeDistance[X][Y][0][1]});
VertexDist[edges[Y].v].erase(it);
if (!VertexDist[edges[Y].v].empty()) {
Distance[X][Y][0][0] = begin(VertexDist[edges[Y].v])->first;
LastEdgeDistance[X][Y][0][0] = begin(VertexDist[edges[Y].v])->second;
}
VertexDist[edges[Y].v].emplace(Distance[X][Y][0][1], LastEdgeDistance[X][Y][0][1]);
}
}
// Computes ShortestPathEdge[][][]
for (int X = 0; X < M; X++) {
for (int Y = 0; Y < M; Y++) {
int V = edges[Y].v;
int &SPE = ShortestPathEdge[X][V][1];
if (Distance[X][Y][1][1] == -1) continue;
if (SPE == -1 || Distance[X][SPE][1][1] > Distance[X][Y][1][1]) {
SPE = Y;
}
}
for (int Y = 0; Y < M; Y++) {
int V = edges[Y].v;
int &SPE = ShortestPathEdge[X][V][0];
if (Distance[X][Y][0][1] == -1) continue;
if (SPE == -1 || Distance[X][SPE][0][1] > Distance[X][Y][0][1]) {
SPE = Y;
}
}
}
}
}
namespace DynamicProgramming {
int X[MAXL];
void Read() {
for (int i = 0; i < L; i++) {
cin >> X[i];
X[i]--;
}
// T = 1
int P, Q;
cin >> P >> Q;
X[--P] = --Q;
}
long long Solve() {
vector<long long> dp(M, INF), next_dp(M, INF);
// Special Case for pos = 0
for (auto i : ShortestPath::adj[X[0]]) {
for (int j = 0; j < M; j++) {
if (ShortestPath::edges[j].v == X[1] && ShortestPath::Distance[i][j][1][1] != -1) {
dp[j] = min(dp[j], ShortestPath::Distance[i][j][1][1]);
}
}
}
for (int pos = 1; pos < L - 1; pos++) {
for (int last_edge = 0; last_edge < M; last_edge++) {
if (ShortestPath::edges[last_edge].v != X[pos]) continue;
int nxt_edge = ShortestPath::ShortestPathEdge[last_edge][X[pos + 1]][1];
if (nxt_edge == -1) continue;
next_dp[nxt_edge] = min(next_dp[nxt_edge],
dp[last_edge] + ShortestPath::Distance[last_edge][nxt_edge][1][1] - ShortestPath::edges[last_edge].w);
int exclude_nxt_edge = ShortestPath::LastEdgeDistance[last_edge][nxt_edge][1][0];
if (exclude_nxt_edge == -1) continue;
next_dp[exclude_nxt_edge] = min(next_dp[exclude_nxt_edge],
dp[last_edge] + ShortestPath::Distance[last_edge][exclude_nxt_edge][1][1] - ShortestPath::edges[last_edge].w);
}
dp = next_dp;
next_dp.assign(M, INF);
}
long long res = *min_element(begin(dp), end(dp));
if (res == INF) res = -1;
return res;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> N >> M >> T >> L;
ShortestPath::Read();
ShortestPath::Solve();
DynamicProgramming::Read();
cout << DynamicProgramming::Solve() << "\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |