結果
| 問題 |
No.1 道のショートカット
|
| コンテスト | |
| ユーザー |
はむ吉🐹
|
| 提出日時 | 2016-06-05 19:16:45 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 3 ms / 5,000 ms |
| コード長 | 4,502 bytes |
| コンパイル時間 | 903 ms |
| コンパイル使用メモリ | 87,772 KB |
| 実行使用メモリ | 5,376 KB |
| 最終ジャッジ日時 | 2024-07-20 16:23:46 |
| 合計ジャッジ時間 | 1,922 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 40 |
ソースコード
#include <ciso646> // 演算子の代替表記を用いる
#include <cstdlib> // EXIT_SUCCESSマクロを用いる
#include <functional> // 優先度付きキューの比較関数としてgreaterを用いる
#include <iostream> // std::cinおよびstd::coutを用いる
#include <queue> // 優先度付きキューを用いる
#include <tuple> // 演算子オーバーロードに用いる
#include <vector> // いつもの
constexpr int IMPOSSIBLE = -1; // 制約下で目的地にたどり着けない
typedef int Money;
typedef int Time;
typedef int Vertex;
// 隣接する頂点の情報
class AdjVertex {
public:
AdjVertex(Vertex dest, Money money, Time time) :
dest_(dest), money_(money), time_(time) {}
Vertex dest() const {
return dest_;
}
Money money() const {
return money_;
}
Time time() const {
return time_;
}
private:
Vertex dest_;
Money money_;
Time time_;
};
typedef std::vector<std::vector<AdjVertex>> AdjVertices;
// 優先度付きキューに入れる状態
class State {
public:
State(Time time, Money money, Vertex vertex) :
time_(time), money_(money), vertex_(vertex) {}
// Getter
Time time() const {
return time_;
}
Money money() const {
return money_;
}
Vertex vertex() const {
return vertex_;
}
// 演算子オーバーロード
// 優先度付きキューに入れるための順序付け
bool operator==(const State& other) const {
auto me = std::tie(time_, money_, vertex_);
auto you = std::tie(other.time_, other.money_, other.vertex_);
return me == you;
}
inline bool operator!=(const State& other) const {
return not(*this == other);
}
bool operator<(const State& other) const {
auto me = std::tie(time_, money_, vertex_);
auto you = std::tie(other.time_, other.money_, other.vertex_);
return me < you;
}
inline bool operator>=(const State& other) const {
return not(*this < other);
}
inline bool operator>(const State& other) const {
return other < *this;
}
inline bool operator<=(const State& other) const {
return not(other < *this);
}
private:
Time time_;
Money money_;
Vertex vertex_;
};
Time compute_min_time(Vertex num_vertices, Money money_limit, const AdjVertices& adj_vertices) {
std::priority_queue<State, std::vector<State>, std::greater<State>> pq;
pq.emplace(0, 0, 0);
while (not pq.empty()) {
// キューから状態を取り出す
auto state0 = pq.top();
pq.pop();
// 取り出した状態がゴールならばそれまでの時間を返す
if (state0.vertex() == num_vertices - 1)
{
return state0.time();
}
for (const auto& v : adj_vertices[state0.vertex()])
{
auto new_money = state0.money() + v.money();
// お金の制限を満たしていればキューに入れる
if (new_money <= money_limit)
{
auto new_time = state0.time() + v.time();
pq.emplace(new_time, new_money, v.dest());
}
}
}
// ゴールにたどり着けないなら
return IMPOSSIBLE;
}
int main() {
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
Vertex num_vertices;
Money money_limit;
int num_edges;
std::cin >> num_vertices >> money_limit >> num_edges;
std::vector<Vertex> sources(num_edges);
std::vector<Vertex> dests(num_edges);
std::vector<Money> moneys(num_edges);
std::vector<Time> times(num_edges);
for (std::size_t i = 0; i < num_edges; i++)
{
std::cin >> sources[i];
sources[i]--;
}
for (std::size_t i = 0; i < num_edges; i++)
{
std::cin >> dests[i];
dests[i]--;
}
for (std::size_t i = 0; i < num_edges; i++)
{
std::cin >> moneys[i];
}
for (std::size_t i = 0; i < num_edges; i++)
{
std::cin >> times[i];
}
// 隣接リストの形でグラフを管理する
AdjVertices adj_vertices(num_vertices, std::vector<AdjVertex>());
for (std::size_t i = 0; i < num_edges; i++)
{
adj_vertices[sources[i]].emplace_back(dests[i], moneys[i], times[i]);
}
auto answer = compute_min_time(num_vertices, money_limit, adj_vertices);
std::cout << answer << std::endl;
return EXIT_SUCCESS;
}
はむ吉🐹