結果
| 問題 |
No.1473 おでぶなおばけさん
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-03-08 13:54:56 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 163 ms / 2,000 ms |
| コード長 | 4,110 bytes |
| コンパイル時間 | 1,906 ms |
| コンパイル使用メモリ | 180,304 KB |
| 実行使用メモリ | 11,712 KB |
| 最終ジャッジ日時 | 2024-09-18 02:31:43 |
| 合計ジャッジ時間 | 8,360 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 47 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using Graph = vector<vector<pll>>;
const ll INF = 1LL << 60;
template <class T>
void chmax(T& a, T b) {
if (b > a) a = b;
}
template <class T>
void chmin(T& a, T b) {
if (b < a) a = b;
}
template <typename T, typename S>
std::ostream& operator<<(std::ostream& os, const pair<T, S>& x) noexcept {
return os << "(" << x.first << ", " << x.second << ")";
}
template <typename T>
void print_vector(vector<T> a) {
cout << '[';
for (int i = 0; i < a.size(); i++) {
cout << a[i];
if (i != a.size() - 1) {
cout << ", ";
}
}
cout << ']' << endl;
}
typedef ll idx;
typedef ll element;
typedef std::function<element(idx)> Query;
class BinarySearch {
public:
// コンストラクタ
BinarySearch();
// [left, right)の範囲で探索する
BinarySearch(Query, idx left, idx right, bool ascending = true);
// 要素xが存在するかどうかを判定し、存在したらそのインデックスを、存在しなかったら-1を返す
idx find(element x) const;
// 要素xの個数をカウントする
ll count(element x) const;
// ascending = true のとき: f(idx)>=xを満たす最小のidxを求める
// ascending = false のとき: f(idx)<xを満たす最小のidxを求める
// (いずれにしても、idxを小さい順から投げていったときにboolが反転する場所のidx)
idx bound(element x) const;
private:
Query query_;
idx left_;
idx right_;
bool ascending_;
};
// コンストラクタ
BinarySearch::BinarySearch() {}
BinarySearch::BinarySearch(Query query, idx left, idx right, bool ascending) {
query_ = query;
left_ = left;
right_ = right;
ascending_ = ascending;
}
idx BinarySearch::find(element x) const {
idx left = left_;
idx right = right_ - 1;
while (right >= left) {
idx mid = left + (right - left) / 2;
element ret = query_(mid);
if (ret == x)
return mid;
else if (!ascending_ ^ (ret > x))
right = mid - 1;
else
left = mid + 1;
}
return -1;
}
ll BinarySearch::count(element x) const {
idx a = bound(x);
idx b = bound(x + 1);
return std::abs(a - b);
}
idx BinarySearch::bound(element x) const {
idx ng = left_ - 1;
idx ok = right_;
while (abs(ok - ng) > 1) {
idx mid = (ok + ng) / 2;
if (!ascending_ ^ (query_(mid) >= x))
ok = mid;
else
ng = mid;
}
return ok;
}
vector<int> bfs(Graph& g, int start, ll weight) {
ll N = g.size();
queue<int> q;
vector<int> dist(N, -1);
vector<int> prevs(N, -1);
dist[start] = 0;
q.push(start);
while (true) {
if (q.empty()) break;
auto current = q.front();
q.pop();
for (auto& v : g[current]) {
if (weight > v.second) continue;
if (dist[v.first] == -1) {
dist[v.first] = dist[current] + 1;
prevs[v.first] = current;
q.push(v.first);
}
}
}
return prevs;
}
ll N, M;
Graph G;
ll f(ll weight) {
auto prevs = bfs(G, 0, weight);
if (prevs[N - 1] == -1) return false;
return true;
}
int main() {
ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin >> N >> M;
G.resize(N);
for (int i = 0; i < M; i++) {
ll a, b, c;
cin >> a >> b >> c;
a--;
b--;
G[a].push_back({b, c});
G[b].push_back({a, c});
}
auto bs = BinarySearch(f, 0, 1000000010, false);
auto best_weight = bs.bound(1) - 1;
auto prevs = bfs(G, 0, best_weight);
ll current = N - 1;
int cnt = 0;
while (true) {
if (current == 0) break;
cnt++;
current = prevs[current];
}
std::cout << best_weight << ' ' << cnt << "\n";
return 0;
}