Click here to view the question Surface
General question:There are \ (n \) cities with \ (M \) one-way roads (the map is not necessarily connected), each city has a degree of development \ (A [I] \), ask you to find two different cities \ (X, Y \) in one path from the capital \ (S \) to the city \ (I \) \ (A [x] \ % A [y] \) maximum (including \ (S \) and \ (I \)), if the output \ (-1 \) cannot be reached \).
A simple question
First, let's consider the following question: if you know a number, how can you find the maximum value after two modulus?
The answer is obvious.Secondary renewal(Strictly large) de-moduloMaximum Value.
The following is a proof:
Set the maximum value of these numbers to \ (max1 \), and strictly limit to \ (max2 \), then
If one number is \ (max1 \) and the other number is \ (a (A <max1) \), the value obtained after the modulo operation is \ (\). It means that when \ (A \) is less than \ (max1 \), the larger \ (A \) is, the better. We can prove that when a number is \ (max1, only when the other number is set to \ (max2 \) Can the result obtained after the modulo operation be maximized and the result obtained is \ (max2 \).
If \ (max1 \) is not obtained, assume that we obtain two numbers \ (X, Y (x ≤ y )\), then the result of their phase modulus must be less than \ (Y \). Because \ (max1 \) cannot be obtained, \ (Y \) can be obtained at maximum \ (max2 \), so the final result must be smaller than \ (max2 \), obviously, none of them get \ (max1 \) and the result is better when one is \ (max2.
To sum up, When a number is the maximum value and a number is the strict limit, the result of the two modulus is the maximum.
Specific Practices
Then the practice of this question is clearer:
First, use \ (Tarjan \) to scale down the source image and convert it into a tree.
Then followTopological orderPre-process the answer to each city.
The answer is output for each query.
Note that \ (x \) and \ (Y \) must be inSame pathI have \ (wa \) countless times...
Code
# Include <bits/stdc ++. h> # define n 400000 # define M 2000000 using namespace STD; int n, m, Q, S, TOT, sum, CNT, top, a [n + 5], lnk [n + 5], nlnk [n + 5], max1 [n + 5], max2 [n + 5], max3 [n + 5], max4 [n + 5], low [n + 5], dfn [n + 5], POS [n + 5], que [n + 5], stack [n + 5], in [n + 5]; bool vis [n + 5]; struct edge {int to, NXT;} e [M + 5], ne [M + 5]; // E [] stores the edges before the point contraction, and NE [] stores the edges after the point contraction void read (Int & X) {x = 0; char CH = getchar (); While (CH <'0' | ch> '9') CH = getchar (); while (CH> = '0' & Ch <= '9') (x * = 10) + = CH-'0', CH = getchar ();} void write (int x) {If (x> 9) write (X/10); putchar (X % 10 + '0');} void add (int x, int y) {e [++ CNT]. to = Y, E [CNT]. NXT = lnk [X], lnk [x] = CNT;} void nadd (int x, int y) {ne [++ CNT]. to = Y, ne [CNT]. NXT = nlnk [X], nlnk [x] = CNT;} void Tarjan (int x) // use Tarjan to scale down the source image, the template does not explain {dfn [x] = low [x] = ++ tot, stack [++ top] = x, vis [x] = 1; for (INT I = lnk [X]; I; I = E [I]. NXT) if (! Dfn [E [I]. to]) Tarjan (E [I]. to), low [x] = min (low [X], low [E [I]. to]); else if (vis [E [I]. to]) low [x] = min (low [X], dfn [E [I]. to]); If (low [x] = dfn [x]) {pos [x] = ++ sum, vis [x] = 0, max1 [Sum] = A [X]; while (stack [Top]! = X) {pos [stack [Top] = sum, vis [stack [Top] = 0; if (a [stack [Top]> max1 [Sum]) max2 [Sum] = max1 [Sum], max1 [Sum] = A [stack [Top]; // update the maximum value and secondary else if (a [stack [Top]! = Max1 [Sum] & A [stack [Top]> max2 [Sum]) max2 [Sum] = A [stack [Top]; top --;} top -- ;}} void topo_sort (INT s) // pre-process the answer in topological order {int h = 0, T = 1; que [1] = s, vis [s] = 1; while (H <t) {int x = que [++ H]; for (INT I = nlnk [X]; I; I = ne [I]. NXT) {++ in [NE [I]. to]; If (vis [NE [I]. to]) continue; vis [NE [I]. to] = 1, que [++ T] = ne [I]. to;} h = 0, T = 1, que [1] = s; while (H <t) {int x = que [++ H]; for (INT I = nlnk [X]; I; I = ne [I]. NXT) {// pre-process the answer max2 [NE [I]. to] = Max (max2 [NE [I]. To], max2 [x]); If (max1 [NE [I]. To]! = Max3 [x]) max2 [NE [I]. to] = max (max2 [NE [I]. to], min (max1 [NE [I]. to], max3 [x]); else max2 [NE [I]. to] = max (max2 [NE [I]. to], max4 [x]); If (max3 [x]> max3 [NE [I]. to]) max4 [NE [I]. to] = max3 [NE [I]. to], max3 [NE [I]. to] = max3 [X]; else if (max3 [NE [I]. to]> max3 [x] & max3 [x]> max4 [NE [I]. to]) max4 [NE [I]. to] = max3 [X]; If (max4 [x]> max3 [NE [I]. to]) max4 [NE [I]. to] = max3 [NE [I]. to], max3 [NE [I]. to] = max4 [NE [I]. to]; else if (max3 [NE [I]. to]> max4 [x] & Max4 [x]> max4 [NE [I]. To]) max4 [NE [I]. To] = max4 [X]; If (! (-- In [NE [I]. to]) que [++ T] = ne [I]. to ;}} int main () {read (N), read (M), read (Q), read (s); For (INT I = 1; I <= N; I ++) read (A [I]); For (INT I = 1, x, y; I <= m; I ++) read (x), read (Y), add (x, y); For (INT I = 1; I <= N; I ++) if (! Dfn [I]) Tarjan (I); // Tarjan contraction point for (INT I = 1; I <= N; I ++) for (Int J = lnk [I]; j = E [J]. NXT) if (Pos [I]! = POS [E [J]. to]) nadd (Pos [I], POS [E [J]. to]); // process the map memcpy (max3, max1, sizeof (max3), memcpy (max4, max2, sizeof (max4 )), topo_sort (Pos [s]); // pre-processing answer while (Q --) {int X; read (x); If (! Vis [POS [x]) printf ("-1"); // determines whether it is connected to S, unconnected output-1 else write (max2 [POS [x]), putchar (''); // If the UNICOM output answer} return 0 ;}
[51nod1815] Investigation Task (Tarjan + topology)