The following figure shows the minimum noise that must be tolerated by a point (that is, the maximum value of the right of the two adjacent points in the path ).
Chinese Translation
Question Link
Question type: Graph Theory/Floyd
Question Analysis:
① Although I was doing graph theory, I started to think DP is acceptable (later I proved that I didn't fully understand the so-called"Relaxation Technology"). The result is a DP that can pass the sample but wa. As a result, the key point is that two adjacent indicator values, which areMutual dependencySpecifically, if there are two adjacent nodes, the D1 value should be calculated according to the D2 value, but the D2 value also depends on the D1 value, so the result is not correct. So I really realized the magic of relaxation technology (relax. It can Slowly tighten two mutually dependent values (minimum value ).
② Floyd. When I thought of Floyd,AlgorithmIt's easy to write it out. D [I] [J] indicates the minimum noise to be tolerated from point I to Point J. Then, you only need to make slight changes to the relaxation, replace General d [I] [k] + d [k] [J] with max (d [I] [K], d [k] [J]), that is, d [I] [J] = min (d [I] [J], max (d [I] [K], d [k] [J]); you can.
In addition, "// If (d [I] [k] <INF & D [k] [J] <inf) // Add this judgment, it can solve the problem that the INF addition may overflow. "It was originally needed, but now it is not the sum but the max, so you don't have to judge.
Code:
①
Incorrect DP. Post it as a warning. (=)
# Include <cstdio> <br/> # include <cstring> <br/> # include <vector> <br/> using namespace STD; <br/> # define maxn 102 // point <br/> # define INF 1 <30 <br/> // # define maxm 1002 // edge <br/> Vector <int> G [maxn]; <br/> int W [maxn] [maxn]; <br/> int d [maxn], vis [maxn]; <br/> inline int max (int x, int y) {return x> Y? X: Y ;}< br/> inline int min (int x, int y) {return x <Y? X: Y ;}< br/> int St, en; <br/> int dp (INT cur) <br/>{< br/> If (cur = sT) return 0; // stop condition <br/> If (vis [cur] = 1) return d [cur]; <br/> vis [cur] =-1; // access <br/> int ans = inf; <br/> for (INT I = 0; I <(INT) g [cur]. size (); I ++) <br/>{< br/> int u = cur, V = G [cur] [I]; <br/> If (vis [v] =-1) continue; // non-extended access <br/> int T = max (dp (V ), W [u] [v]); <br/> ans = min (T, ANS); <br/>}< br/> vis [cur] = 1; <br/> return d [cur] = Ans; // If ANS is still INF, it means they cannot reach <br/>}< br/> int C, S, Q; // point, edge, start-end logarithm <br/> void clear () <br/>{< br/> for (INT I = 1; I <= C; I ++) <br/> If (! G [I]. empty () <br/> G [I]. clear (); <br/>}< br/> int read_graph () <br/>{< br/> int OK = 1; <br/> scanf ("% d", & C, & S, & Q); <br/> If (! C &&! S &&! Q) return 0; <br/> for (INT I = 0; I <s; I ++) <br/>{< br/> int C1, C2, di; <br/> scanf ("% d", & C1, & C2, & di); <br/> G [C1]. push_back (C2); <br/> G [C2]. push_back (C1); <br/> W [C1] [C2] = W [C2] [C1] = di; <br/>}< br/> return 1; <br/>}< br/> int main () <br/>{< br/> int T = 1; <br/> while (read_graph ()) <br/>{< br/> If (T! = 1) printf ("/N"); // empty rows between cases //! A blank column <br/> printf ("case # % d/N", t ++) is displayed for each organization ); <br/> for (INT I = 0; I <q; I ++) <br/>{< br/> memset (VIS, 0, sizeof (VIS )); <br/> scanf ("% d", & St, & en); <br/> int T = dp (en ); <br/> If (t = inf) printf ("no path/N"); <br/> else printf ("% d/N", t ); // <br/>}< br/> clear (); <br/>}< br/>}
②
Floyd
# Include <cstdio> <br/> # include <cstring> <br/> using namespace STD; <br/> # define maxn 102 // point <br/> # define INF 1 <30 <br/> int d [maxn] [maxn]; //! <Br/> inline int max (int x, int y) {return x> Y? X: Y ;}< br/> inline int min (int x, int y) {return x <Y? X: Y ;}< br/> int St, en; <br/> int C, S, Q; // vertex, edge, start-end logarithm </P> <p> void Floyd () <br/> {<br/> for (int K = 1; k <= C; k ++) <br/> for (INT I = 1; I <= C; I ++) <br/> for (Int J = 1; j <= C; j ++) <br/> // If (d [I] [k] <INF & D [k] [J] <inf) // Add this judgment, this can solve the problem that INF addition may overflow <br/> d [I] [J] = min (d [I] [J], max (d [I] [K], d [k] [J]); //! <Br/>}< br/> int read_graph () <br/> {<br/> scanf ("% d", & C, & S, & Q); <br/> If (! C &&! S &&! Q) return 0; <br/> for (INT I = 1; I <= C; I ++) <br/> for (Int J = 1; j <= C; j ++) <br/> d [I] [J] = I = J? 0: INF; <br/> for (INT I = 0; I <s; I ++) <br/> {<br/> int C1, C2, di; <br/> scanf ("% d", & C1, & C2, & di ); <br/> d [C1] [C2] = d [C2] [C1] = di; <br/>}< br/> return 1; <br/>}< br/> int main () <br/>{< br/> int T = 1; <br/> while (read_graph ()) <br/>{< br/> If (T! = 1) printf ("/N"); // empty rows between cases <br/> printf ("case # % d/N", t ++ ); <br/> Floyd (); <br/> for (INT I = 0; I <q; I ++) <br/>{< br/> scanf ("% d", & St, & en); <br/> int T = d [st] [En]; <br/> If (t = inf) printf ("no path/N"); <br/> else printf ("% d/N", t ); <br/>}< br/>}