結果
問題 | No.2301 Namorientation |
ユーザー | nu50218 |
提出日時 | 2023-05-12 22:13:19 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 604 ms / 3,000 ms |
コード長 | 6,188 bytes |
コンパイル時間 | 4,417 ms |
コンパイル使用メモリ | 259,608 KB |
実行使用メモリ | 57,196 KB |
最終ジャッジ日時 | 2024-05-06 12:16:59 |
合計ジャッジ時間 | 19,856 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 1 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 1 ms
5,376 KB |
testcase_08 | AC | 1 ms
5,376 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 313 ms
28,500 KB |
testcase_13 | AC | 303 ms
26,252 KB |
testcase_14 | AC | 604 ms
45,312 KB |
testcase_15 | AC | 343 ms
31,348 KB |
testcase_16 | AC | 469 ms
39,336 KB |
testcase_17 | AC | 304 ms
29,536 KB |
testcase_18 | AC | 511 ms
40,084 KB |
testcase_19 | AC | 244 ms
24,764 KB |
testcase_20 | AC | 508 ms
39,776 KB |
testcase_21 | AC | 342 ms
30,768 KB |
testcase_22 | AC | 446 ms
57,196 KB |
testcase_23 | AC | 495 ms
56,328 KB |
testcase_24 | AC | 373 ms
47,628 KB |
testcase_25 | AC | 311 ms
36,984 KB |
testcase_26 | AC | 378 ms
47,028 KB |
testcase_27 | AC | 574 ms
45,460 KB |
testcase_28 | AC | 560 ms
45,588 KB |
testcase_29 | AC | 562 ms
45,460 KB |
testcase_30 | AC | 583 ms
45,464 KB |
testcase_31 | AC | 572 ms
45,464 KB |
ソースコード
#line 1 "main.cpp" #ifdef LOCAL #include <local.hpp> #else #pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,popcnt,lzcnt,abm,bmi,bmi2") #include <bits/stdc++.h> #define debug(...) ((void)0) #define postprocess(...) ((void)0) #endif #line 1 "library/graph/shortest_path.hpp" #include <bits/stdc++.h> template <typename weight> struct shortest_path { const weight unreachable = std::numeric_limits<weight>::max(); shortest_path() : _computed(false) {} shortest_path(const int& n, const int& m = 0) : _n(n), _computed(false) { if (m) _edges.reserve(m); } void set_number(const int& n, const int& m = 0) { _n = n; if (m) _edges.reserve(m); } void add_edge(const int& i, const int& j, const weight& w) { assert(0 <= i && i < _n); assert(0 <= j && j < _n); _edges.emplace_back(i, j, w); } void compute(const int& s) { _s = s; _computed = true; _adj.resize(_n); for (auto&& e : _edges) { auto [u, v, w] = e; _adj[u].emplace_back(v, w); } _dist.resize(_n); std::fill(_dist.begin(), _dist.end(), unreachable); _par.resize(_n); std::fill(_par.begin(), _par.end(), -1); // select best algorithm if (!std::is_integral<weight>::value) { _dijkstra(s); return; } for (auto&& [_, __, cost] : _edges) { if (cost >= 2) { _dijkstra(s); return; } } for (auto&& [_, __, cost] : _edges) { if (cost == 0) { _bfs01(s); return; } } _bfs(s); } int s() { assert(_computed); return _s; } std::vector<weight> dist() { assert(_computed); return _dist; } weight dist(const int& t) { assert(_computed); return _dist[t]; } std::vector<int> path(int t) { assert(_computed); assert(0 <= t && t < _n); assert(_dist[t] != unreachable); std::vector<int> ret; while (t != _s) { ret.push_back(t); t = _par[t]; } ret.push_back(_s); std::reverse(ret.begin(), ret.end()); return ret; } private: // input values int _n; int _s; std::vector<std::tuple<int, int, weight>> _edges; // computed values bool _computed; std::vector<std::vector<std::pair<int, weight>>> _adj; std::vector<weight> _dist; std::vector<int> _par; void _bfs(const int& s) { std::queue<int> que; que.emplace(s); _dist[s] = 0; while (!que.empty()) { auto v = que.front(); que.pop(); for (auto&& [to, _] : _adj[v]) { if (_dist[to] == unreachable) { _dist[to] = _dist[v] + 1; _par[to] = v; que.emplace(to); } } } } void _bfs01(const int& s) { std::deque<int> que; _dist[s] = 0; que.emplace_back(s); while (!que.empty()) { auto v = que.front(); que.pop_front(); for (auto&& [to, cost] : _adj[v]) { weight d = _dist[v] + cost; if (d < _dist[to]) { _dist[to] = d; _par[to] = v; if (cost) { que.emplace_back(to); } else { que.emplace_front(to); } } } } } void _dijkstra(const int& s) { using que_class = std::pair<weight, int>; std::priority_queue<que_class, std::vector<que_class>, std::greater<que_class>> que; _dist[s] = 0; que.emplace(0, s); while (!que.empty()) { auto [d, v] = que.top(); que.pop(); if (_dist[v] != d) continue; for (auto&& [to, cost] : _adj[v]) { if (_dist[to] <= d + cost) continue; _dist[to] = d + cost; _par[to] = v; que.emplace(_dist[to], to); } } } }; #line 12 "main.cpp" using namespace std; using ll = long long; using ld = long double; vector<vector<int>> adj; deque<int> cycle; vector<bool> visited; bool rec(int par = -1, int v = 0) { if (visited[v]) { while (cycle.front() != v) cycle.pop_front(); return true; } visited[v] = true; cycle.push_back(v); for (auto&& u : adj[v]) { if (u == par) continue; if (rec(v, u)) return true; } cycle.pop_back(); return false; } void solve([[maybe_unused]] int test) { int N; cin >> N; adj.resize(N); visited = vector<bool>(N, false); map<pair<int, int>, int> edge; shortest_path<int> sp(N); for (int i = 0; i < N; i++) { int A, B; cin >> A >> B; A--; B--; edge[{A, B}] = i; adj[A].push_back(B); adj[B].push_back(A); sp.add_edge(A, B, 1); sp.add_edge(B, A, 1); } rec(); bool in_cycle[N]; for (int i = 0; i < N; i++) { in_cycle[i] = false; } for (auto&& v : cycle) { in_cycle[v] = true; } bool ans[N]; for (int i = 0; i < (int)cycle.size(); i++) { bool right = true; int a = cycle[i]; int b = cycle[(i + 1) % (int)cycle.size()]; if (!(a < b)) swap(a, b), right = false; assert(edge.count({a, b})); int e = edge[{a, b}]; ans[e] = right; } sp.compute(cycle[0]); for (auto&& [E, e] : edge) { auto [a, b] = E; if (in_cycle[a] && in_cycle[b]) continue; ans[e] = sp.dist(a) > sp.dist(b); } for (int i = 0; i < N; i++) { cout << (ans[i] ? "->" : "<-") << endl; } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t = 1; // cin >> t; for (int i = 1; i <= t; i++) { solve(i); } postprocess(); }