QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#132292 | #5506. Hyperloop | ClHg2 | WA | 140ms | 7960kb | C++14 | 4.7kb | 2023-07-29 13:46:53 | 2023-07-29 13:46:54 |
Judging History
answer
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <memory>
#include <queue>
#include <string>
#include <utility>
#include <vector>
namespace {
using std::cin;
using std::cout;
using std::int64_t;
using std::size_t;
using std::uint32_t;
namespace base {
template <typename T, size_t... sizes>
struct NestedArray {};
template <typename T, size_t size, size_t... sizes>
struct NestedArray<T, size, sizes...> {
using Type = std::array<typename NestedArray<T, sizes...>::Type, size>;
};
template <typename T>
struct NestedArray<T> {
using Type = T;
};
template <typename T, size_t... sizes>
using Array = typename NestedArray<T, sizes...>::Type;
void OptimizeIO() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
}
void OptimizeIO(const std::string &input_file, const std::string &output_file) {
static std::ifstream input_stream(input_file);
static std::ofstream output_stream(output_file);
cin.rdbuf(input_stream.rdbuf()), cout.rdbuf(output_stream.rdbuf());
cin.tie(nullptr), cout.tie(nullptr);
}
} // namespace base
using base::Array;
const int kMaxN = 1.0e5 + 5, kMaxM = 3.0e5 + 5, kMaxW = 5.0e4 + 5,
kMaxLogW = 17, kMaxK = kMaxN * kMaxLogW, kInf = 1.0e9 + 5;
const uint32_t kBase = 19260817;
int n, m, max_w;
Array<int, kMaxN> pre, w, dis;
Array<uint32_t, kMaxW> pow_base;
Array<bool, kMaxN> vis;
Array<std::vector<std::pair<int, int>>, kMaxN> edge;
std::priority_queue<std::pair<int, int>> q;
class PersistentSegmentTree {
public:
void set_n(int n) { n_ = n; }
void Clear() {
std::fill_n(rt_.begin() + 1, n, 0);
std::fill_n(lc_.begin() + 1, tot_, 0);
std::fill_n(rc_.begin() + 1, tot_, 0);
std::fill_n(cnt_.begin() + 1, tot_, 0);
std::fill_n(hash_.begin() + 1, tot_, 0);
tot_ = 0;
}
void Insert(int p, int q, int x) { rc_[q] = Insert(rt_[p], 1, n_, x); }
bool Cmp(int p, int q, int x, int y) {
return Cmp(rt_[p], rt_[q], 1, n_, x, y) == -1;
}
private:
int Insert(int p, int l, int r, int x);
int Cmp(int p, int q, int l, int r, int x, int y);
int n_, tot_;
Array<int, kMaxN> rt_;
Array<int, kMaxK> lc_, rc_, cnt_;
Array<uint32_t, kMaxK> hash_;
};
int PersistentSegmentTree::Insert(int p, int l, int r, int x) {
int q = ++tot_;
hash_[q] = hash_[p] + pow_base[x], cnt_[q] = cnt_[p] + 1;
if (l == r) return q;
int mid = (l + r) >> 1;
if (x <= mid) {
lc_[q] = Insert(lc_[p], l, mid, x), rc_[q] = rc_[p];
} else {
lc_[q] = lc_[p], rc_[q] = Insert(rc_[p], mid + 1, r, x);
}
return q;
}
int PersistentSegmentTree::Cmp(int p, int q, int l, int r, int x, int y) {
uint32_t hash_p = hash_[p], hash_q = hash_[q];
if (x >= l && x <= r) hash_p += pow_base[x];
if (y >= l && y <= r) hash_q += pow_base[y];
if (hash_p == hash_q) return 0;
if (l == r) return cnt_[p] < cnt_[q] ? -1 : 1;
int mid = (l + r) >> 1, ans = Cmp(rc_[p], rc_[q], mid + 1, r, x, y);
if (ans == 0) ans = Cmp(lc_[p], lc_[q], l, mid, x, y);
return ans;
}
PersistentSegmentTree persistent_segment_tree;
void InitPowBase() {
pow_base[0] = 1;
for (int i = 1; i <= max_w; ++i) pow_base[i] = pow_base[i - 1] * kBase;
}
void Dijkstra() {
persistent_segment_tree.set_n(max_w);
persistent_segment_tree.Clear();
pre[1] = 0;
std::fill_n(dis.begin() + 1, n, kInf), dis[1] = 0;
std::fill_n(vis.begin() + 1, n, false);
q.emplace(0, 1);
while (!q.empty()) {
int u = q.top().second;
q.pop();
if (vis[u]) continue;
vis[u] = true;
if (u != 1) persistent_segment_tree.Insert(pre[u], u, w[u]);
for (const auto &e : edge[u]) {
int v = e.first, w = e.second;
if (dis[u] + w < dis[v]) {
dis[v] = dis[u] + w, q.emplace(-dis[v], v), pre[v] = u, ::w[v] = w;
} else if (dis[u] + w == dis[v] &&
persistent_segment_tree.Cmp(pre[v], u, ::w[v], w)) {
pre[v] = u, ::w[v] = w;
}
}
}
}
void Print() {
std::vector<int> path;
for (int i = n; i; i = pre[i]) path.emplace_back(i);
cout << path.size() << "\n";
for (int i = path.size() - 1; i >= 0; --i) cout << path[i] << " ";
cout << "\n";
}
void Solve() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) edge[i].clear();
max_w = 0;
while (m--) {
int u, v, w;
cin >> u >> v >> w, max_w = std::max(max_w, w);
edge[u].emplace_back(v, w), edge[v].emplace_back(u, w);
}
InitPowBase();
Dijkstra();
Print();
}
int Main() {
base::OptimizeIO();
int t;
cin >> t;
while (t--) Solve();
return 0;
}
} // namespace
int main() { return Main(); }
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 7728kb
input:
2 4 6 1 2 1 1 3 2 2 3 1 2 4 2 3 4 1 1 4 4 6 11 1 2 9 2 3 12 3 4 3 4 5 5 5 6 10 6 1 22 2 4 9 3 6 1 4 6 5 2 5 2 3 5 8
output:
3 1 2 4 5 1 2 5 3 6
result:
ok correct (2 test cases)
Test #2:
score: -100
Wrong Answer
time: 140ms
memory: 7960kb
input:
600 320 1547 204 81 13768 232 97 9939 97 249 3719 201 109 14322 183 132 40881 142 143 1 275 186 24548 18 236 7907 30 317 11845 131 130 1 311 300 11704 141 92 41925 174 191 32128 119 120 1 184 183 1 310 309 1 283 270 25477 233 141 36076 212 92 13770 307 110 40656 218 137 14033 180 85 41892 200 199 44...
output:
184 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 10...
result:
wrong answer Contestant's path is not optimal lexicographically (test case 2)