[yukicoder] No. 848 なかよし旅行

問題

方針

解説を見ても良く分かりませんでした。

似たような問題で、CSA の良問があります。

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int N, M, P, Q, T;
static const ll INF = 100000000000000;
 
struct Node {
  int id;
  ll cost;
  Node() {}
  Node(int id, ll cost) : id(id), cost(cost){}
  bool operator< (const Node& node) const {
    return node.cost < cost;
  } 
};

// N: 頂点数, E: 辺の数, d: 距離 を格納する配列, 
// t: 始点, flag: true なら 無向辺, false なら 有向辺
void dijkstra(int N, int E, ll d[], int t, int from[], int to[], ll cost[], bool flag) {
  static const int WHITE = 0;
  static const int GRAY = 1;
  static const int BLACK = 2;
  
  int color[N];
  vector<Node> adj[N];
  for (int i = 0; i < N; i++) {
    d[i] = INF;
    color[i] = WHITE;
  }
  // 隣接リストの作成
  for (int i = 0; i < E; i++) {
    adj[from[i]].push_back(Node(to[i], cost[i]));
    if (flag) adj[to[i]].push_back(Node(from[i], cost[i]));
  }
  priority_queue<Node> pq;
  d[t] = 0;
  pq.push(Node(t, 0));
  while (!pq.empty()) {
    Node f = pq.top();
    pq.pop();
    int u = f.id;
    color[u] = BLACK;
    if (d[u] < f.cost) continue;
    for (int j = 0; j < adj[u].size(); j++) {
      int v = adj[u][j].id;
      if (color[v] == BLACK) continue;
      if (d[v] > d[u] + adj[u][j].cost) {
        d[v] = d[u] + adj[u][j].cost;
        pq.push(Node(v, d[v]));
        color[v] = GRAY;
      }
    }
  }
}

int main() {
  
  cin >> N >> M >> P >> Q >> T;
  int a[M], b[M];
  ll c[M];
  for (int i = 0; i < M; i++) {
    cin >> a[i] >> b[i] >> c[i];
    a[i]--;
    b[i]--;
  }
  P--;
  Q--;
  ll d[N], dP[N], dQ[N];
  dijkstra(N, M, d, 0, a, b, c, true);
  dijkstra(N, M, dP, P, a, b, c, true);
  dijkstra(N, M, dQ, Q, a, b, c, true);

  if (d[P] * 2 > T || d[Q] * 2 > T) {
    cout << "-1\n";
    return 0;
  }
  if (d[P] + dP[Q] + dQ[0] <= T) {
    cout << T << "\n";
    return 0;
  }
  ll ans = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (d[i] + dP[i] + dP[j] + d[j] > T) continue;
      if (d[i] + dQ[i] + dQ[j] + d[j] > T) continue;
      ans = max(ans, T - max(dP[i] + dP[j], dQ[i] + dQ[j]));
    }
  }
  cout << ans << "\n";
  return 0;
}