Submission #856941

#TimeUsernameProblemLanguageResultExecution timeMemory
856941mihajanezThousands Islands (IOI22_islands)C++17
100 / 100
112 ms28556 KiB
#include <bits/stdc++.h> #include <variant> #include <vector> #include <list> #include <stack> #include <queue> using namespace std; vector<int > construct_journey( vector<list<pair<int, int>>> nodes, int fork, list<pair<int, int>>c2, list<pair<int, int>>c1_fork_to_cycle_pairs, list<pair<int, int>>c1_cycle_pairs, bool two_cycles) { vector<int> journey; if (two_cycles) { list<int> start_to_fork, c1_fork_to_cycle, c1_cycle, c2_fork_to_cycle, c2_cycle; // component2 int begin_cycle_c2 = c2.back().first; c2_cycle.push_front(c2.back().second); c2.pop_back(); while (c2.back().first != begin_cycle_c2) { c2_cycle.push_front(c2.back().second); c2.pop_back(); } while (c2.back().first != fork) { c2_fork_to_cycle.push_front(c2.back().second); c2.pop_back(); } while (!c2.empty()) { start_to_fork.push_front(c2.back().second); c2.pop_back(); } start_to_fork.pop_front(); // component1 for (auto& i : c1_fork_to_cycle_pairs) { c1_fork_to_cycle.push_back(i.second); } for (auto& i : c1_cycle_pairs) { c1_cycle.push_back(i.second); } journey.reserve(2 * start_to_fork.size() + 4 * c1_fork_to_cycle.size() + 2 * c1_cycle.size() + 4 * c2_fork_to_cycle.size() + 2 * c2_cycle.size()); copy(start_to_fork.cbegin(), start_to_fork.cend(), back_inserter(journey)); copy(c1_fork_to_cycle.cbegin(), c1_fork_to_cycle.cend(), back_inserter(journey)); copy(c1_cycle.cbegin(), c1_cycle.cend(), back_inserter(journey)); copy(c1_fork_to_cycle.crbegin(), c1_fork_to_cycle.crend(), back_inserter(journey)); copy(c2_fork_to_cycle.cbegin(), c2_fork_to_cycle.cend(), back_inserter(journey)); copy(c2_cycle.cbegin(), c2_cycle.cend(), back_inserter(journey)); copy(c2_fork_to_cycle.crbegin(), c2_fork_to_cycle.crend(), back_inserter(journey)); copy(c1_fork_to_cycle.cbegin(), c1_fork_to_cycle.cend(), back_inserter(journey)); copy(c1_cycle.crbegin(), c1_cycle.crend(), back_inserter(journey)); copy(c1_fork_to_cycle.crbegin(), c1_fork_to_cycle.crend(), back_inserter(journey)); copy(c2_fork_to_cycle.cbegin(), c2_fork_to_cycle.cend(), back_inserter(journey)); copy(c2_cycle.crbegin(), c2_cycle.crend(), back_inserter(journey)); copy(c2_fork_to_cycle.crbegin(), c2_fork_to_cycle.crend(), back_inserter(journey)); copy(start_to_fork.crbegin(), start_to_fork.crend(), back_inserter(journey)); } else { list<int> start_to_fork, fork_to_join1, fork_to_join2, cycle; // component2 while (c2.front().first != fork) { start_to_fork.push_back(c2.front().second); c2.pop_front(); } start_to_fork.push_back(c2.front().second); start_to_fork.pop_front(); c2.pop_front(); for (auto& i : c2) { fork_to_join2.push_back(i.second); } for (auto& i : c1_cycle_pairs) { cycle.push_back(i.second); } int join = c2.back().first; // component1 auto it = c1_fork_to_cycle_pairs.cbegin(); while (it != c1_fork_to_cycle_pairs.cend() && (*it).first != join) { fork_to_join1.push_back((*it++).second); } // join before the cycle if (it != c1_fork_to_cycle_pairs.cend()) { fork_to_join1.push_back((*it++).second); list<int> join_to_cycle; while (it != c1_fork_to_cycle_pairs.cend()) { join_to_cycle.push_back((*it++).second); } journey.reserve(2 * start_to_fork.size() + 2 * fork_to_join1.size() + 2 * fork_to_join2.size() + 4 * join_to_cycle.size() + 2 * cycle.size()); copy(start_to_fork.cbegin(), start_to_fork.cend(), back_inserter(journey)); copy(fork_to_join1.cbegin(), fork_to_join1.cend(), back_inserter(journey)); copy(join_to_cycle.cbegin(), join_to_cycle.cend(), back_inserter(journey)); copy(cycle.cbegin(), cycle.cend(), back_inserter(journey)); copy(join_to_cycle.crbegin(), join_to_cycle.crend(), back_inserter(journey)); copy(fork_to_join1.crbegin(), fork_to_join1.crend(), back_inserter(journey)); copy(fork_to_join2.cbegin(), fork_to_join2.cend(), back_inserter(journey)); copy(join_to_cycle.cbegin(), join_to_cycle.cend(), back_inserter(journey)); copy(cycle.crbegin(), cycle.crend(), back_inserter(journey)); copy(join_to_cycle.crbegin(), join_to_cycle.crend(), back_inserter(journey)); copy(fork_to_join2.crbegin(), fork_to_join2.crend(), back_inserter(journey)); copy(start_to_fork.crbegin(), start_to_fork.crend(), back_inserter(journey)); } // join inside the cycle else { journey.reserve(2 * start_to_fork.size() + 2 * fork_to_join1.size() + 2 * fork_to_join2.size() + 2 * cycle.size()); copy(start_to_fork.cbegin(), start_to_fork.cend(), back_inserter(journey)); copy(fork_to_join1.cbegin(), fork_to_join1.cend(), back_inserter(journey)); copy(cycle.cbegin(), cycle.cend(), back_inserter(journey)); copy(fork_to_join1.crbegin(), fork_to_join1.crend(), back_inserter(journey)); copy(fork_to_join2.cbegin(), fork_to_join2.cend(), back_inserter(journey)); // rotate the cycle while (c1_cycle_pairs.back().first != join) { c1_cycle_pairs.push_front(c1_cycle_pairs.back()); c1_cycle_pairs.pop_back(); cycle.push_front(cycle.back()); cycle.pop_back(); } copy(cycle.crbegin(), cycle.crend(), back_inserter(journey)); copy(fork_to_join2.crbegin(), fork_to_join2.crend(), back_inserter(journey)); copy(start_to_fork.crbegin(), start_to_fork.crend(), back_inserter(journey)); } } return journey; } list<pair<int, int>> construct_cycle(vector<list<pair<int, int>>> nodes, int begin_cycle, vector<bool> unavailable_nodes) { vector<bool> visited(nodes.size(), false); vector<pair<int, int>> predecessors(nodes.size()); queue<int> bfs_queue; visited[begin_cycle] = true; bfs_queue.push(begin_cycle); while (!bfs_queue.empty()) { int last_node = bfs_queue.front(); bfs_queue.pop(); for (auto& next_edge : nodes[last_node]) { if (!visited[next_edge.first] && !unavailable_nodes[next_edge.first]) { visited[next_edge.first] = true; bfs_queue.push(next_edge.first); predecessors[next_edge.first] = make_pair(last_node, next_edge.second); } else if (next_edge.first == begin_cycle) { list<pair<int, int>> cycle; cycle.push_front(make_pair(next_edge.first, next_edge.second)); while (last_node != begin_cycle) { cycle.push_front(make_pair(last_node, predecessors[last_node].second)); last_node = predecessors[last_node].first; } return cycle; } } } return {}; } variant<bool, vector<int>> find_journey(int N, int M, vector<int> U, vector<int> V) { // pair out_node, out_edge vector<list<pair<int, int>>> nodes(N); for (auto i = 0; i < U.size(); i++) { nodes[U[i]].push_back(make_pair(V[i], i)); } vector<bool> visited(nodes.size(), false), in_path(nodes.size(), false), begin_cycle(nodes.size(), false), goal(nodes.size(), false); stack<list<pair<int, int>>::const_iterator> dfs_stack; list<pair<int, int>> path; list<pair<int, int>> c1_fork_to_cycle, c1_cycle; bool seek_component2 = false; int fork = -1; visited[0] = true; in_path[0] = true; dfs_stack.push(nodes[0].cbegin()); path.push_back(make_pair(0, -1)); while (!dfs_stack.empty()) { int top_node = path.back().first; goal[top_node] = seek_component2; // first popped cycle -> found the cycle of component1 if (!seek_component2 && begin_cycle[top_node]) { seek_component2 = true; c1_cycle = construct_cycle(nodes, top_node, in_path); visited = vector<bool>(nodes.size(), false); for (auto& i : c1_cycle) { visited[i.first] = true; goal[i.first] = true; } for (auto& i : path) { visited[i.first] = true; } } // top_node has more successors if (dfs_stack.top() != nodes[path.back().first].cend()) { auto& [successor_node, successor_edge] = *dfs_stack.top(); dfs_stack.top()++; // set new fork if (seek_component2 && fork == -1) { fork = top_node; } if (!visited[successor_node]) { visited[successor_node] = true; in_path[successor_node] = true; dfs_stack.push(nodes[successor_node].cbegin()); path.push_back(make_pair(successor_node, successor_edge)); } // found a cycle in component1 else if (!seek_component2 && in_path[successor_node]) { begin_cycle[successor_node] = true; } // found component2 else if (goal[successor_node]) { path.push_back(make_pair(successor_node, successor_edge)); // cycle found if (in_path[successor_node]) { return construct_journey(nodes, fork, path, c1_fork_to_cycle, c1_cycle, true); } // path to component1 found else { return construct_journey(nodes, fork, path, c1_fork_to_cycle, c1_cycle, false); } } } // top_node has no more successors -> pop it off the stack else { goal[top_node] = false; if (top_node == fork) { fork = -1; } if (seek_component2 && fork == -1) { goal[top_node] = true; c1_fork_to_cycle.push_front(path.back()); } in_path[top_node] = false; dfs_stack.pop(); path.pop_back(); } } return false; }

Compilation message (stderr)

islands.cpp: In function 'std::variant<bool, std::vector<int, std::allocator<int> > > find_journey(int, int, std::vector<int>, std::vector<int>)':
islands.cpp:169:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  169 |  for (auto i = 0; i < U.size(); i++) {
      |                   ~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...