Explanation
Let's solve the subtask first. Let's reverse the graph so that in this query, we are solving for the longest path from to an unblocked node. Here, we can just use DP to compute the longest path to every possible node . If stores the longest path from to , then , over all where and are connected by an edge and is reachable from in the reverse graph. Since it is guaranteed , this can be done with a single sweep.
Now, let's bring in sqrt decomposition. The variable in question is the number of blocked nodes, denoted as . Let's denote and suppose all queries have . Since the sum of over all queries is bounded by , there can be no more than queries. The number of queries is small enough that we can run an DP algorithm each time, leading to a runtime.
To handle queries with , we have to do some preprocessing. For each node, we can store the longest paths that ends at that node, each originating from a different initial node. This needs to be done with careful pruning of paths with different lengths originating from the same node. This precomputation is approximately , since we need to sort the longest paths after we process each node. To answer queries, we can just loop through the longest paths of , and find the longest one starting at an unblocked node. This will also take time.
Warning: Choosing B
We do not want to choose such that it equals exactly! It is apparent that the latter case is much more memory and runtime heavy than the former case, so we need to weigh down to minimize the effects of the second case. In my code, I use .
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;const int SQ = 100; // cutoff for sqrt decompint main() {cin.tie(0)->sync_with_stdio(0);int n, m, q;cin >> n >> m >> q;vector<vector<int>> rg(n);for (int i = 0; i < m; i++) {
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!