結果
問題 | No.2914 正閉路検出 |
ユーザー | noya2 |
提出日時 | 2024-10-04 21:36:20 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 133 ms / 2,000 ms |
コード長 | 22,660 bytes |
コンパイル時間 | 3,556 ms |
コンパイル使用メモリ | 293,136 KB |
実行使用メモリ | 23,928 KB |
最終ジャッジ日時 | 2024-10-04 21:36:32 |
合計ジャッジ時間 | 10,802 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 1 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 1 ms
5,248 KB |
testcase_05 | AC | 1 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 1 ms
5,248 KB |
testcase_08 | AC | 2 ms
5,248 KB |
testcase_09 | AC | 1 ms
5,248 KB |
testcase_10 | AC | 1 ms
5,248 KB |
testcase_11 | AC | 1 ms
5,248 KB |
testcase_12 | AC | 1 ms
5,248 KB |
testcase_13 | AC | 1 ms
5,248 KB |
testcase_14 | AC | 2 ms
5,248 KB |
testcase_15 | AC | 2 ms
5,248 KB |
testcase_16 | AC | 2 ms
5,248 KB |
testcase_17 | AC | 1 ms
5,248 KB |
testcase_18 | AC | 1 ms
5,248 KB |
testcase_19 | AC | 8 ms
5,248 KB |
testcase_20 | AC | 15 ms
5,248 KB |
testcase_21 | AC | 5 ms
5,248 KB |
testcase_22 | AC | 17 ms
5,248 KB |
testcase_23 | AC | 13 ms
5,248 KB |
testcase_24 | AC | 21 ms
5,248 KB |
testcase_25 | AC | 3 ms
5,248 KB |
testcase_26 | AC | 4 ms
5,248 KB |
testcase_27 | AC | 23 ms
5,248 KB |
testcase_28 | AC | 28 ms
5,248 KB |
testcase_29 | AC | 64 ms
11,008 KB |
testcase_30 | AC | 7 ms
5,248 KB |
testcase_31 | AC | 23 ms
5,248 KB |
testcase_32 | AC | 27 ms
5,248 KB |
testcase_33 | AC | 14 ms
8,196 KB |
testcase_34 | AC | 105 ms
12,792 KB |
testcase_35 | AC | 80 ms
12,812 KB |
testcase_36 | AC | 81 ms
12,816 KB |
testcase_37 | AC | 101 ms
23,928 KB |
testcase_38 | AC | 67 ms
23,108 KB |
testcase_39 | AC | 109 ms
18,424 KB |
testcase_40 | AC | 131 ms
22,908 KB |
testcase_41 | AC | 118 ms
17,528 KB |
testcase_42 | AC | 132 ms
20,988 KB |
testcase_43 | AC | 127 ms
21,888 KB |
testcase_44 | AC | 107 ms
17,664 KB |
testcase_45 | AC | 129 ms
21,756 KB |
testcase_46 | AC | 121 ms
19,964 KB |
testcase_47 | AC | 125 ms
19,840 KB |
testcase_48 | AC | 111 ms
18,812 KB |
testcase_49 | AC | 133 ms
21,244 KB |
testcase_50 | AC | 122 ms
18,552 KB |
testcase_51 | AC | 44 ms
9,600 KB |
testcase_52 | AC | 48 ms
11,704 KB |
testcase_53 | AC | 49 ms
11,736 KB |
testcase_54 | AC | 50 ms
11,736 KB |
ソースコード
#line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp" using namespace std; #include<bits/stdc++.h> #line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp" namespace noya2 { template <typename T, typename U> ostream &operator<<(ostream &os, const pair<T, U> &p){ os << p.first << " " << p.second; return os; } template <typename T, typename U> istream &operator>>(istream &is, pair<T, U> &p){ is >> p.first >> p.second; return is; } template <typename T> ostream &operator<<(ostream &os, const vector<T> &v){ int s = (int)v.size(); for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i]; return os; } template <typename T> istream &operator>>(istream &is, vector<T> &v){ for (auto &x : v) is >> x; return is; } void in() {} template <typename T, class... U> void in(T &t, U &...u){ cin >> t; in(u...); } void out() { cout << "\n"; } template <typename T, class... U, char sep = ' '> void out(const T &t, const U &...u){ cout << t; if (sizeof...(u)) cout << sep; out(u...); } template<typename T> void out(const vector<vector<T>> &vv){ int s = (int)vv.size(); for (int i = 0; i < s; i++) out(vv[i]); } struct IoSetup { IoSetup(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); cerr << fixed << setprecision(7); } } iosetup_noya2; } // namespace noya2 #line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp" namespace noya2{ const int iinf = 1'000'000'007; const long long linf = 2'000'000'000'000'000'000LL; const long long mod998 = 998244353; const long long mod107 = 1000000007; const long double pi = 3.14159265358979323; const vector<int> dx = {0,1,0,-1,1,1,-1,-1}; const vector<int> dy = {1,0,-1,0,1,-1,-1,1}; const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const string alp = "abcdefghijklmnopqrstuvwxyz"; const string NUM = "0123456789"; void yes(){ cout << "Yes\n"; } void no(){ cout << "No\n"; } void YES(){ cout << "YES\n"; } void NO(){ cout << "NO\n"; } void yn(bool t){ t ? yes() : no(); } void YN(bool t){ t ? YES() : NO(); } } // namespace noya2 #line 2 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp" #line 6 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp" namespace noya2{ unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){ if (a == 0 || b == 0) return a + b; int n = __builtin_ctzll(a); a >>= n; int m = __builtin_ctzll(b); b >>= m; while (a != b) { int mm = __builtin_ctzll(a - b); bool f = a > b; unsigned long long c = f ? a : b; b = f ? b : a; a = (c - b) >> mm; } return a << std::min(n, m); } template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(std::abs(a),std::abs(b))); } long long sqrt_fast(long long n) { if (n <= 0) return 0; long long x = sqrt(n); while ((x + 1) * (x + 1) <= n) x++; while (x * x > n) x--; return x; } template<typename T> T floor_div(const T n, const T d) { assert(d != 0); return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0); } template<typename T> T ceil_div(const T n, const T d) { assert(d != 0); return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0); } template<typename T> void uniq(std::vector<T> &v){ std::sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); } template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; } template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; } template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; } } // namespace noya2 #line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp" #define rep(i,n) for (int i = 0; i < (int)(n); i++) #define repp(i,m,n) for (int i = (m); i < (int)(n); i++) #define reb(i,n) for (int i = (int)(n-1); i >= 0; i--) #define all(v) (v).begin(),(v).end() using ll = long long; using ld = long double; using uint = unsigned int; using ull = unsigned long long; using pii = pair<int,int>; using pll = pair<ll,ll>; using pil = pair<int,ll>; using pli = pair<ll,int>; namespace noya2{ /* ~ (. _________ . /) */ } using namespace noya2; #line 2 "c.cpp" #line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/potentialized_dsu.hpp" #line 6 "/Users/noya2/Desktop/Noya2_library/data_structure/potentialized_dsu.hpp" #line 2 "/Users/noya2/Desktop/Noya2_library/misc/concepts.hpp" #include<concepts> namespace noya2 { template<class monoid> concept Monoid = requires { typename monoid::value_type; {monoid::op(declval<typename monoid::value_type>(),declval<typename monoid::value_type>())} -> std::same_as<typename monoid::value_type>; {monoid::e()} -> std::same_as<typename monoid::value_type>; }; template<class group> concept Group = requires { requires Monoid<group>; {group::inv(declval<typename group::value_type>())} -> std::same_as<typename group::value_type>; }; } // namespace noya2 #line 8 "/Users/noya2/Desktop/Noya2_library/data_structure/potentialized_dsu.hpp" namespace noya2 { template<Group G> struct potentialized_dsu { using T = typename G::value_type; potentialized_dsu (int n = 0) : _n(n), parent_or_size(n,-1), pot(n, G::e()) {} // p[u] = op(p[v], d), u is higher than v by d int merge(int u, int v, T d){ int x = leader(u), y = leader(v); if (x == y){ if (diff(u, v) == d) return x; else return -1; } d = G::op(potential(u), G::inv(G::op(potential(v), d))); if (-parent_or_size[x] < -parent_or_size[y]){ d = G::inv(d); std::swap(x, y); } parent_or_size[x] += parent_or_size[y]; parent_or_size[y] = x; pot[y] = d; return x; } int leader(int v){ assert(0 <= v && v < _n); if (parent_or_size[v] < 0) return v; int l = leader(parent_or_size[v]); pot[v] = G::op(pot[parent_or_size[v]], pot[v]); return parent_or_size[v] = l; } bool same(int u, int v){ return leader(u) == leader(v); } int size(int v){ return -parent_or_size[leader(v)]; } T potential(int v){ leader(v); return pot[v]; } // p[u] = op(p[v], d) // d = op(inv(p[v]), p[u]) T diff(int u, int v){ return G::op(G::inv(potential(v)), potential(u)); } std::vector<std::vector<int>> groups() { std::vector<int> leader_buf(_n), group_size(_n); for (int i = 0; i < _n; i++) { leader_buf[i] = leader(i); group_size[leader_buf[i]]++; } std::vector<std::vector<int>> result(_n); for (int i = 0; i < _n; i++) { result[i].reserve(group_size[i]); } for (int i = 0; i < _n; i++) { result[leader_buf[i]].push_back(i); } result.erase( std::remove_if(result.begin(), result.end(), [&](const std::vector<int>& v) { return v.empty(); }), result.end()); return result; } private: int _n; std::vector<int> parent_or_size; std::vector<T> pot; }; } // namespace noya2 #line 2 "/Users/noya2/Desktop/Noya2_library/tree/heavy_light_decomposition.hpp" #line 2 "/Users/noya2/Desktop/Noya2_library/tree/simple_tree.hpp" #line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/csr.hpp" #line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/csr.hpp" #include<ranges> #line 7 "/Users/noya2/Desktop/Noya2_library/data_structure/csr.hpp" namespace noya2::internal { template<class E> struct csr { csr () {} csr (int _n) : n(_n) {} csr (int _n, int m) : n(_n){ start.reserve(m); elist.reserve(m); } // ACL style constructor (do not have to call build) csr (int _n, const std::vector<std::pair<int,E>> &idx_elem) : n(_n), start(_n + 2), elist(idx_elem.size()) { for (auto &[i, e] : idx_elem){ start[i + 2]++; } for (int i = 1; i < n; i++){ start[i + 2] += start[i + 1]; } for (auto &[i, e] : idx_elem){ elist[start[i + 1]++] = e; } prepared = true; } int add(int idx, E elem){ int eid = start.size(); start.emplace_back(idx); elist.emplace_back(elem); return eid; } void build(){ if (prepared) return ; int m = start.size(); std::vector<E> nelist(m); std::vector<int> nstart(n + 2, 0); for (int i = 0; i < m; i++){ nstart[start[i] + 2]++; } for (int i = 1; i < n; i++){ nstart[i + 2] += nstart[i + 1]; } for (int i = 0; i < m; i++){ nelist[nstart[start[i] + 1]++] = elist[i]; } swap(elist,nelist); swap(start,nstart); prepared = true; } const auto operator[](int idx) const { return std::ranges::subrange(elist.begin()+start[idx],elist.begin()+start[idx+1]); } auto operator[](int idx){ return std::ranges::subrange(elist.begin()+start[idx],elist.begin()+start[idx+1]); } const auto operator()(int idx, int l, int r) const { return std::ranges::subrange(elist.begin()+start[idx]+l,elist.begin()+start[idx]+r); } auto operator()(int idx, int l, int r){ return std::ranges::subrange(elist.begin()+start[idx]+l,elist.begin()+start[idx]+r); } int n; std::vector<int> start; std::vector<E> elist; bool prepared = false; }; } // namespace noya2::internal #line 5 "/Users/noya2/Desktop/Noya2_library/tree/simple_tree.hpp" namespace noya2 { struct simple_tree { internal::csr<int> g; simple_tree () {} simple_tree (int _n) : g(_n, (_n - 1)*2) { if (_n == 1){ g.build(); } } void add_edge(int u, int v){ g.add(u, v); int id = g.add(v, u); if (id + 1 == (g.n - 1)*2) g.build(); } void input(int indexed = 1){ for (int i = 0; i < g.n - 1; i++){ int u, v; cin >> u >> v; u -= indexed, v -= indexed; add_edge(u, v); } } void input_parents(int indexed = 1){ for (int i = 0; i < g.n - 1; i++){ int v; cin >> v; v -= indexed; add_edge(i + 1, v); } } const auto operator[](int v) const { return g[v]; } auto operator[](int v){ return g[v]; } int size() const { return g.n; } }; } // namespace noya2 #line 4 "/Users/noya2/Desktop/Noya2_library/tree/heavy_light_decomposition.hpp" namespace noya2 { struct hld_tree { internal::csr<int> g; hld_tree () {} hld_tree (int _n, int _root = 0) : g(_n,(_n - 1)*2), n(_n), root(_root) { if (_n == 1){ build(); } } hld_tree (simple_tree _g, int _root = 0) : g(_g.g), n(_g.g.n), root(_root){ build(); } size_t size() const { return g.n; } void add_edge(int u, int v){ g.add(u, v); int id = g.add(v, u); if (id + 1 == (n - 1)*2) build(); } void input(int indexed = 1){ for (int i = 0; i < n - 1; i++){ int u, v; cin >> u >> v; u -= indexed, v -= indexed; add_edge(u, v); } } void input_parents(int indexed = 1){ for (int i = 0; i < n - 1; i++){ int v; cin >> v; v -= indexed; add_edge(i + 1, v); } } int depth(int v) const { return dep[v]; } int parent(int v) const { if (v == root) return -1; return g[v].back(); } int degree(int v) const { return g[v].size(); } int subtree_size(int v) const { return sub[v]; } // if d > dep[v], return -1 int la(int v, int d) const { while (v != -1){ int u = nxt[v]; if (down[v] - d >= down[u]){ v = tour[down[v] - d]; break; } d -= down[v] - down[u] + 1; v = parent(u); } return v; } int lca(int u, int v) const { while (nxt[u] != nxt[v]){ if (down[u] < down[v]) swap(u,v); u = parent(nxt[u]); } return dep[u] < dep[v] ? u : v; } int dist(int u, int v) const { return dep[u] + dep[v] - 2*dep[lca(u,v)]; } // if d > dist(from, to), return -1 int jump(int from, int to, int d) const { int l = lca(from,to); if (d <= dep[from] - dep[l]){ return la(from, d); } d -= dep[from] - dep[l]; if (d <= dep[to] - dep[l]){ return la(to, dep[to] - dep[l] - d); } return -1; } // seg.set(index(v), X[v]); int index(int vertex) const { return down[vertex]; } int index_from_edge(int u, int v) const { return (dep[u] < dep[v] ? down[v] : down[u]); } // X[vertex(i)] = seg.get(i); int vertex(int index) const { return tour[index]; } int subtree_l(int v) const { return down[v]; } int subtree_r(int v) const { return down[v] + sub[v]; } // if r == v, return true bool is_in_subtree(int r, int v) const { return subtree_l(r) <= subtree_l(v) && subtree_l(v) < subtree_r(r); } bool is_in_path(int lv, int mv, int rv) const { return dist(lv,mv) + dist(mv,rv) == dist(lv,rv); } // dist, v1, v2 tuple<int,int,int> diameter(){ int v1 = max_element(dep.begin(),dep.end()) - dep.begin(); vector<int> dist_from_v1(n,numeric_limits<int>::max()); queue<int> que; que.push(v1); dist_from_v1[v1] = 0; while (!que.empty()){ int v = que.front(); que.pop(); for (int u : g[v]){ if (dist_from_v1[u] > dist_from_v1[v]+1){ dist_from_v1[u] = dist_from_v1[v]+1; que.push(u); } } } int v2 = max_element(dist_from_v1.begin(),dist_from_v1.end()) - dist_from_v1.begin(); return make_tuple(dist_from_v1[v2],v1,v2); } // vertex array : vector<int> {from, v1, v2, ... , to} vector<int> path(int from, int to){ int l = lca(from,to); const int sizf = dep[from]-dep[l], sizt = dep[to]-dep[l]; vector<int> pf = {from}, pt; pf.reserve(sizf+1); pt.reserve(sizt); for (int i = 0; i < sizf; i++){ from = parent(from); pf.push_back(from); } for (int i = 0; i < sizt; i++){ pt.push_back(to); to = parent(to); } pf.insert(pf.end(),pt.rbegin(),pt.rend()); return pf; } template<typename F> void path_query(int u, int v, bool vertex, const F &f){ int l = lca(u,v); for (auto [s, t] : ascend(u, l)){ f(t, s + 1); } if (vertex) f(down[l], down[l] + 1); for (auto [s, t] : descend(l, v)){ f(s, t + 1); } } template<typename F> void path_noncommutative_query(int u, int v, bool vertex, const F &f){ int l = lca(u,v); for (auto [s, t] : ascend(u, l)){ f(s + 1, t); // l > r ok } if (vertex) f(down[l],down[l] + 1); for (auto [s, t] : descend(l, v)){ f(s, t + 1); // l > r ok } } template<typename F> void subtree_query(int v, bool vertex, const F &f){ f(down[v] + (vertex ? 0 : 1), down[v] + sub[v]); } // adjacent to v const auto operator[](int v) const { return g[v]; } auto operator[](int v){ return g[v]; } // only child const auto operator()(int v) const { return g(v, 0, degree(v) - (v == root ? 0 : 1)); } auto operator()(int v){ return g(v, 0, degree(v) - (v == root ? 0 : 1)); } private: int n, root; vector<int> dep, sub, down, tour, nxt; // v is ancestor of u. // enumerate [closed] intervals of down ( interval [l, r] may hold l > r ). vector<pair<int,int>> ascend(int u, int v){ vector<pair<int,int>> res; while (nxt[u] != nxt[v]){ res.emplace_back(down[u], down[nxt[u]]); u = parent(nxt[u]); } if (u != v) res.emplace_back(down[u], down[v]+1); return res; } // u is ancestor of v. // enumerate [closed] intervals of down ( interval [l, r] may hold l > r ). vector<pair<int,int>> descend(int u, int v){ if (u == v) return {}; if (nxt[u] == nxt[v]){ return {pair<int,int>(down[u]+1, down[v])}; } vector<pair<int,int>> res = descend(u, parent(nxt[v])); res.emplace_back(down[nxt[v]], down[v]); return res; } void build(){ g.build(); init_sz(); init_hld(); } /* setup dep, sub if v is not root, g[v].back() is parent of v. if v is not leaf (i.e. v has child), g[v].front() is heavy child of v. */ void init_sz(){ dep.resize(n, 0); sub.resize(n, 1); auto dfs = [&](auto sfs, int v, int f) -> void { for (int &u : g[v]){ // only one chance to take parent as u. if (u == f) swap(g[v].back(), u); // twice means u is the last element of g[v], i.e. parent of v. if (u == f) break; dep[u] = dep[v]+1; sfs(sfs, u, v); sub[v] += sub[u]; if (sub[g[v].front()] < sub[u]){ swap(g[v].front(), u); } } }; dfs(dfs, root, -1); } /* setup down, tour, nxt only heavy child c of v, nxt[c] = nxt[v]. for other child c, nxt[c] = c. */ void init_hld(){ down.resize(n); tour.resize(n); nxt.resize(n); nxt[root] = root; int clock = 0; auto dfs = [&](auto sfs, int v) -> void { down[v] = clock++; tour[down[v]] = v; // in case of no child, nothing to do if ((*this)(v).empty()) return ; // heavy child nxt[(*this)(v).front()] = nxt[v]; sfs(sfs, (*this)(v).front()); // other child for (int u : (*this)(v).next()){ nxt[u] = u; sfs(sfs, u); } }; dfs(dfs, root); } public: struct compressed_tree : public simple_tree { using simple_tree::simple_tree; using simple_tree::operator=; hld_tree &g; compressed_tree (hld_tree &g_, vector<int> vs) : g(g_){ auto comp = [&](int lv, int rv){ return g.index(lv) < g.index(rv); }; sort(vs.begin(),vs.end(),comp); int sz = vs.size(); for (int i = 0; i < sz-1; i++){ vs.emplace_back(g.lca(vs[i],vs[i+1])); } sort(vs.begin(),vs.end(),comp); vs.erase(unique(vs.begin(),vs.end()),vs.end()); sz = vs.size(); (*this) = simple_tree(sz); real_vertex = vs; for (int i = 0; i < sz; i++){ g.virtual_vertex[real_vertex[i]] = i; } stack<int> st; st.push(0); for (int i = 1; i < sz; i++){ while (!g.is_in_subtree(real_vertex[st.top()], real_vertex[i])) st.pop(); (*this).add_edge(st.top(),i); st.push(i); } } vector<int> real_vertex; int real_v(int virtual_v) const { return real_vertex[virtual_v]; } int virtual_v(int real_v) const { return g.virtual_vertex[real_v]; } size_t size() const { return real_vertex.size(); } }; compressed_tree compressed_tree_gen(const vector<int> &vs){ if ((int)virtual_vertex.size() != n) virtual_vertex.resize(n); return compressed_tree(*this, vs); } vector<int> virtual_vertex; }; } // namespace noya2 #line 2 "/Users/noya2/Desktop/Noya2_library/misc/monoids.hpp" #line 4 "/Users/noya2/Desktop/Noya2_library/misc/monoids.hpp" namespace noya2{ template<typename T> struct max_monoid { using value_type = T; static constexpr T op(const T &a, const T &b){ return max(a,b); } static constexpr T e(){ return std::numeric_limits<T>::min(); } static constexpr T inv(const T &a){ return e(); } }; template<typename T> struct min_monoid { using value_type = T; static constexpr T op(const T &a, const T &b){ return min(a,b); } static constexpr T e(){ return std::numeric_limits<T>::max(); } static constexpr T inv(const T &a){ return e(); } }; template<typename T> struct plus_group { using value_type = T; static constexpr T op(const T &a, const T &b){ return a + b; } static constexpr T e(){ return T(0); } static constexpr T inv(const T &a){ return -a; } }; template<typename T> struct xor_group { using value_type = T; static constexpr T op(const T &a, const T &b){ return a ^ b; } static constexpr T e(){ return T(0); } static constexpr T inv(const T &a){ return a; } }; } // namespace noya2 #line 6 "c.cpp" void solve(){ int n, m; in(n,m); potentialized_dsu<plus_group<ll>> pd(n); hld_tree g(n); map<pii,int> mp; int sv = -1, tv = -1, eid = -1; rep(i,m){ int u, v; in(u,v); u--, v--; ll c; in(c); if (!pd.same(u,v)){ pd.merge(u,v,c); g.add_edge(u,v); mp[pii(u,v)] = i+1; continue; } ll h = pd.diff(u,v); if (h == c) continue; if (h < c){ sv = v; tv = u; } else { sv = u; tv = v; } eid = i+1; } if (sv == -1){ out(-1); return ; } rep(i,n){ if (pd.same(0,i)) continue; pd.merge(0,i,0); g.add_edge(0,i); } auto path = g.path(sv,tv); int sz = path.size(); out(sz); out(sv+1); vector<int> ans(sz); rep(i,sz-1){ int u = path[i]; int v = path[i+1]; if (!mp.contains({u,v})){ swap(u,v); } ans[i] = mp[pii(u,v)]; } ans[sz-1] = eid; out(ans); } int main(){ int t = 1; //in(t); while (t--) { solve(); } }