I had a good idea when I got this question, but I only tried to find the code to cut the top on weekdays. I didn't think carefully about the code of zhiqiao. At that time, I felt like my graph theory was just getting started .. The question is hard to understand. It is to determine whether to connect first, and directly output 0 if not connected. If there is a heavy edge, then there is no bridge between the two points with a heavy edge. In addition, no soldiers on the bridge should guard and send a person to blow up. ...
# Include <iostream> # include <cstdio> # include <cstring> # include <vector> # include <algorithm> using namespace std; const int maxn = 1500; int dfs_clock, current_clock, ans, current_cc; int adj [maxn] [maxn], iscut [maxn], vis [maxn], pre [maxn], low [maxn]; vector <int> G [maxn]; int n, m, a, B, c, INF = 10000000; void dfs (int u) {vis [u] = 1; // PREVISIT (u); for (int I = 0; I <G [u]. size (); I ++) {Int v = G [u] [I]; if (! Vis [v]) dfs (v);} // POSTVISIT (u); operations after access node u} void find_cc () // connect component number {current_cc = 0; memset (vis, 0, sizeof (vis); for (int u = 1; u <= n; u ++) if (! Vis [u]) {current_cc ++; dfs (u) ;}} int dfs_bridge (int u, int fa) // The parent node of u in the dfs tree is fa {int lowu = pre [u] = ++ dfs_clock; int child = 0; // Number of subnodes for (int I = 0; I <G [u]. size (); I ++) {int v = G [u] [I]; if (! Pre [v]) // no access to v {child ++; int lowv = dfs_bridge (v, u); lowu = min (lowu, lowv ); if (lowv> = pre [u]) {iscut [u] = true; // determine if (lowv> pre [u] & amp; adj [u] [v]! =-2) // the judgment of the bridge can be flexibly handled by ans = min (ans, adj [u] [v]);} else if (pre [v] <pre [u] & v! = Fa) lowu = min (lowu, pre [v]); // use reverse edge to update u's low function} if (fa <0 & child = 1) {// but does not need to be added to determine whether to judge the bridge separately? Iscut [u] = 0; // It should be a situation where a single node is used to judge the bridge and cut the top} low [u] = lowu; return lowu;} void init () {memset (pre, 0, sizeof (pre); memset (iscut, 0, sizeof (iscut); memset (adj,-1, sizeof (adj )); for (int I = 0; I <= n; I ++) G [I]. clear () ;}int main () {while (scanf ("% d", & n, & m )! = EOF) {if (! N &&! M) break; init (); while (m --) {scanf ("% d", & a, & B, & c ); if (adj [a] [B] =-1) {G [a]. push_back (B); G [B]. push_back (a); adj [a] [B] = c; adj [B] [a] = c ;} else // there must be two sides between two points that cannot be a bridge {adj [a] [B] =-2; adj [B] [a] =-2;} ans = INF; dfs (1); find_cc (); // printf ("~ % D \ n ", current_cc); if (current_cc> = 2) {printf (" 0 \ n "); continue;} else dfs_bridge (1,-1 ); if (ans = 0) printf ("1 \ n"); else if (ans = INF) printf ("-1 \ n "); else printf ("% d \ n", ans);} return 0 ;}