Find and contract all SCC, and then select the block with the smallest number of points in the block with the outbound degree 0 or the inbound degree 0 as the independent block, this makes it hard to connect to other blocks, and the rest of the points are strongly connected!
# Include <cstdio> # include <vector> # include <stack> # include <cstring> using namespace STD; const int n = 100010; vector <int> G [N]; int pre [N], lowlink [N], sccno [N], num [N], dfs_clock, scc_cnt; stack <int> S; void DFS (int u) {pre [u] = lowlink [u] = ++ dfs_clock; S. push (U); For (INT I = 0; I <G [u]. size (); ++ I) {int v = G [u] [I]; If (! Pre [v]) {DFS (V); lowlink [u] = min (lowlink [u], lowlink [v]);} else if (! Sccno [v]) lowlink [u] = min (pre [v], lowlink [u]);} If (lowlink [u] = pre [u]) {scc_cnt ++; For (;) {int x = S. top (); S. pop (); sccno [x] = scc_cnt; num [scc_cnt] ++; If (x = u) Break ;}} void find_scc (int n) {dfs_clock = scc_cnt = 0; memset (Num, 0, sizeof (Num); memset (PRE, 0, sizeof (pre); memset (sccno, 0, sizeof (sccno); For (INT I = 1; I <= N; ++ I) if (! Pre [I]) DFS (I);} int t, n, m; int in [N], out [N]; int main () {While (scanf ("% d", & T )! = EOF) {int icase = 1; while (t --) {scanf ("% d", & N, & M); For (INT I = 0; I <= N; ++ I) g [I]. clear (); int TMP = m, Maxx = 0x3fffffff; while (TMP --) {int A, B; scanf ("% d", & A, & B ); G [A]. push_back (B);} find_scc (n); // printf ("% d \ n", scc_cnt); If (scc_cnt = 1) {printf ("case % d: -1 \ n ", icase ++); continue;} memset (in, 0, sizeof (in); memset (Out, 0, sizeof (out )); for (INT I = 1; I <= N; ++ I) for (Int J = 0; j <G [I]. size (); ++ J) {int v = G [I] [J]; If (sccno [I]! = Sccno [v]) out [sccno [I] ++, in [sccno [v] ++ ;}for (INT I = 1; I <= scc_cnt; ++ I) if (Num [I] <Maxx & (in [I] = 0 | out [I] = 0) Maxx = num [I]; printf ("case % d:", icase ++); printf ("% d \ n", N * (n-1) -M-Maxx * (N-Maxx ));}}}