結果
| 問題 |
No.1 道のショートカット
|
| コンテスト | |
| ユーザー |
vjudge1
|
| 提出日時 | 2025-09-04 21:28:25 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 3 ms / 5,000 ms |
| コード長 | 2,714 bytes |
| コンパイル時間 | 1,124 ms |
| コンパイル使用メモリ | 107,816 KB |
| 実行使用メモリ | 7,720 KB |
| 最終ジャッジ日時 | 2025-09-04 21:28:28 |
| 合計ジャッジ時間 | 2,442 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 40 |
ソースコード
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
const int INF = 1e9;
struct Edge {
int to, cost, time;
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int N, C, V;
cin >> N >> C >> V;
vector<Edge> edges;
edges.reserve(V);
vector<int> graph_start(N + 1, 0);
// Read all input first for better performance
vector<int> input(4 * V);
for (int i = 0; i < 4 * V; i++) {
cin >> input[i];
}
// Count edges per node using reference
for (int i = 0; i < V; i++) {
int& s = input[i];
graph_start[s]++; // s is 1-indexed
}
// Convert counts to start indices (prefix sum)
for (int i = 1; i <= N; i++) {
graph_start[i] += graph_start[i - 1];
}
// Store edges using direct memory access
vector<Edge> graph_edges(V);
vector<int> edge_count(N + 1, 0);
for (int i = 0; i < V; i++) {
int& s = input[i];
int& t = input[V + i];
int& cost = input[2 * V + i];
int& time = input[3 * V + i];
int pos = graph_start[s - 1] + edge_count[s]++;
graph_edges[pos] = {t - 1, cost, time};
}
// DP array with reference optimization
vector<vector<int>> dp(N, vector<int>(C + 1, INF));
dp[0][C] = 0;
// Use references and direct pointer access for maximum speed
for (int i = 0; i < N; i++) {
int start_idx = graph_start[i];
int end_idx = graph_start[i + 1];
int edge_count = end_idx - start_idx;
if (edge_count == 0) continue;
// Get pointer to the first edge for this node
const Edge* edges_ptr = graph_edges.data() + start_idx;
for (int k = C; k >= 0; k--) {
int& current_dp = dp[i][k];
if (current_dp == INF) continue;
// Process all edges using pointer arithmetic
for (int j = 0; j < edge_count; j++) {
const Edge& e = edges_ptr[j];
if (k >= e.cost) {
int& target = dp[e.to][k - e.cost];
int new_time = current_dp + e.time;
if (new_time < target) {
target = new_time;
}
}
}
}
}
// Find minimum result using reference
int result = INF;
const vector<int>& last_node = dp[N - 1];
for (int k = 0; k <= C; k++) {
const int& val = last_node[k];
if (val < result) {
result = val;
}
}
cout << (result == INF ? -1 : result) << endl;
return 0;
}
vjudge1