結果
| 問題 | No.3653 Space-Time Courier |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-08-04 00:29:57 |
| 言語 | C++23(gcc16) (gcc 16.1.0 + boost 1.90.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,904 bytes |
| 記録 | |
| コンパイル時間 | 1,955 ms |
| コンパイル使用メモリ | 244,960 KB |
| 実行使用メモリ | 6,400 KB |
| 最終ジャッジ日時 | 2026-08-28 21:13:38 |
| 合計ジャッジ時間 | 3,952 ms |
|
ジャッジサーバーID (参考情報) |
judge2_0 / judge3_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 10 WA * 18 |
ソースコード
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <numeric>
#include <random>
using namespace std;
const long long INF = 1e18;
struct Edge {
int u, v, w;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
if (!(cin >> N >> M)) return 0;
vector<long long> P(N + 1);
for (int i = 1; i <= N; i++) cin >> P[i];
vector<Edge> edges(M);
vector<vector<pair<int, int>>> adj(N + 1);
for (int i = 0; i < M; i++) {
cin >> edges[i].u >> edges[i].v >> edges[i].w;
adj[edges[i].u].push_back({edges[i].v, edges[i].w});
}
// 正しいポテンシャル h の計算 (SPFA)
vector<long long> h(N + 1, 0);
queue<int> q;
vector<bool> in_q(N + 1, true);
for (int i = 1; i <= N; i++) q.push(i);
while (!q.empty()) {
int u = q.front();
q.pop();
in_q[u] = false;
for (auto& edge : adj[u]) {
int v = edge.first;
int w = edge.second;
if (h[v] > h[u] + w) {
h[v] = h[u] + w;
if (!in_q[v]) {
q.push(v);
in_q[v] = true;
}
}
}
}
// Johnson の再重み付け
vector<vector<pair<int, long long>>> adj_rw(N + 1);
for (auto& e : edges) {
adj_rw[e.u].push_back({e.v, e.w + h[e.u] - h[e.v]});
}
// 【嘘ポイント】ランダム K=200 点のみ Dijkstra
vector<int> sources(N);
iota(sources.begin(), sources.end(), 1);
mt19937 rng(1337);
shuffle(sources.begin(), sources.end(), rng);
int K = min(N, 200);
long long ans_cost = INF;
int ans_count = 0;
using PLI = pair<long long, int>;
for (int i = 0; i < K; i++) {
int src = sources[i];
vector<long long> dist(N + 1, INF);
priority_queue<PLI, vector<PLI>, greater<PLI>> pq;
dist[src] = 0;
pq.push({0, src});
while (!pq.empty()) {
auto [d, u] = pq.top();
pq.pop();
if (d > dist[u]) continue;
for (auto& edge : adj_rw[u]) {
int v = edge.first;
long long rw = edge.second;
if (dist[v] > d + rw) {
dist[v] = d + rw;
pq.push({dist[v], v});
}
}
}
for (int v = 1; v <= N; v++) {
if (src == v || dist[v] == INF) continue;
long long real_dist = dist[v] - h[src] + h[v];
long long cost = real_dist + P[src] + P[v];
if (cost < ans_cost) {
ans_cost = cost;
ans_count = 1;
} else if (cost == ans_cost) {
ans_count++;
}
}
}
if (ans_cost == INF) cout << -1 << "\n";
else cout << ans_cost << " " << ans_count << "\n";
return 0;
}