For a graph, ask how many directed edges can be added to make the graph become strongly connected.
The source image has a ring and is scaled down to build a graph. In this Dag, we can find that to make the graph into a strongly connected graph, it must be connected to a ring.
Adding the least edge to join the ring means to link the points with the inbound and outbound degrees 0 on the graph, so other points can reach each other.
So the answer is max (point with 0 inbound and point with 0 outbound)
# Include <iostream> # include <cstring> # include <string> # include <cstdio> # include <cmath> # include <algorithm> # include <vector> # include <queue> # include <map> # define INF 0x3f3f3f # define EPS 1e-6 # define ll _ int64 # define M 20010 // Number of using namespace STD in the figure; int sta [m], top; // stack bool vis [m] In the Tarjan algorithm; // check whether int dfn [m] is in the stack; // deep-first search for the access order int low [m]; // The earliest order int ccnt that can be traced back; // The number of strongly connected components int ID of the directed graph; // Index Number Vector <int> E [m ]; // The adjacent table indicates the vector <int> part [m]; // obtain the strongly connected component result int INPART [m]; // record the int degree [m] In the strongly connected component of the vertex number; // record the degree vector of each strongly connected component <int> edge [m]; // create an int ans, n, m, DP [m], in [m], point [m], out [m]; void Tarjan (int x) {int I, j; dfn [x] = low [x] = ID ++; vis [x] = 1; STA [++ top] = X; for (I = 0; I <E [X]. size (); I ++) {J = E [x] [I]; If (dfn [J] =-1) {Tarjan (j ); low [x] = min (low [X], low [J]);} else if (vis [J]) low [x] = min (low [X], dfn [J]);} If (dfn [x] = low [x ]) {Do {J = sta [top --]; vis [J] = 0; part [ccnt]. push_back (j); INPART [J] = ccnt; point [ccnt] ++;} while (J! = X); ccnt ++ ;}} void solve (int n) {memset (STA,-1, sizeof Sta); memset (VIS, 0, sizeof vis ); memset (dfn,-1, sizeof dfn); memset (low,-1, sizeof low); memset (point, 0, sizeof point); Top = ccnt = id = 0; for (INT I = 1; I <= N; I ++) if (dfn [I] =-1) Tarjan (I) ;} int DFS (INT X) {If (DP [x]) return DP [X]; DP [x] = point [X]; int I; for (I = 0; I <edge [X]. size (); I ++) {int TMP = edge [x] [I]; DP [x] = max (DP [X], point [x] + DFS (TMP);} return DP [X];} Int main () {int n, m, I, j, a, B, T; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & M); for (I = 0; I <= N; I ++) {part [I]. clear (); e [I]. clear (); edge [I]. clear () ;}while (M --) {scanf ("% d", & A, & B); e [A]. push_back (B);} solve (n); memset (in, 0, sizeof in); memset (Out, 0, sizeof out); for (I = 1; I <= N; I ++) // enumerate the edges in the source image {for (j = 0; j <E [I]. size (); j ++) {A = INPART [I]; B = INPART [E [I] [J]; // if (! = B) {in [B] ++; out [a] ++; edge [A]. push_back (B) ;}}a = B = 0; for (I = 0; I <ccnt; I ++) // {If (in [I] = 0) A ++; If (out [I] = 0) B ++;} If (ccnt = 1) printf ("0 \ n"); else printf ("% d \ n", max (A, B);} return 0 ;}