/* HDU 4635 stronugly connected: A simple (no duplicate edge, no self-ring: You just direct yourself to your side) Directed Graph. If it is strongly connected, output-1. Otherwise, the output can add up to a maximum number of edges but not strongly connected. The status of the added edge is that there are two strongly connected blocks (including the number of points n, m ), any two points inside each of them have two sides in different directions, and the two blocks have only one side, the edge in the other direction is sacrificed because of non-strong connectivity (the number is N * m). A strongly connected graph with n points can have at most N * (n-1) edges, m items already exist, N * m items are sacrificed, and cannot be created. The rest is visible, and the blocks without inbound or outbound values are enumerated, minimum N * m */# include <stdio. h ># include <stack> using namespace STD; const int n = 100000 + 10; stack <int> S; int ret; struct node {int V, next;} e [n ]; Int INS [N], Fang [N], head [N], low [N], belong [N]; int Ru [N], Chu [N]; int numd [N]; int n, m, Yong; void Tarjan (int K) {Int J, U; Fang [k] = low [k] = Yong ++; INS [k] = 1; S. push (k); // Why stack is used for strong connectivity? The upstream node of the stack may be connected to the same component. It is impossible for non-stack nodes to be accessed on the same connected component (accessed but not on the stack, may it be the same connected component? If the accessed node is not on the stack (not the same connected component, they have already been out of the stack, it indicates that their root is still relatively high, not updated) for (j = head [k]; j = E [J]. next) {u = E [J]. v; If (Fang [u] = 0) {Tarjan (U); If (low [u] <low [k]) low [k] = low [u];} else if (INS [u] & Fang [u] <low [k]) // U may have been accessed on the previous Road, or U is the ancestor of K. They must be the same connected component. What is different from dual-connected is: he asked him not to cross himself, so even if he had a back-to-edge, the updates would be the same in the morning and evening. What dual-connection worried about was that he updated the updates in advance, which led his children to be updated in advance, therefore, Fang [local node]> low [child] = low [local node] = low [parent node of this node] Low [k] = Fang [u];} If (low [k] = Fang [k]) // the lowest one it can find does not surpass itself, it indicates that the following is a connected component {RET ++; do {J = S. top (); S. pop (); INS [J] = 0; belong [J] = ret;} while (J! = K) ;}} void Adde (int A, int B) {e [Yong]. V = B; E [Yong]. next = head [a]; head [a] = Yong ++;} int main () {int T, Ti, A, B, I, J; scanf ("% d", & T); For (Ti = 1; Ti <= T; ++ Ti) {ret = 0; Yong = 1; scanf ("% d", & N, & M); memset (Head, 0, sizeof (head); for (I = 0; I <m; ++ I) {scanf ("% d", & A, & B); Adde (a, B) ;}yong = 1; memset (INS, 0, sizeof (INS); memset (Fang, 0, sizeof (Fang); for (I = 1; I <= N; I ++) {If (Fang [I] = 0) {Tarjan (I) ;}} if (ret = 1) {printf ("case % d:-1 \ N ", Ti); continue;} memset (CHU, 0, sizeof (CHU); memset (RU, 0, sizeof (Ru); memset (numd, 0, sizeof (numd); for (I = 1; I <= N; I ++) {numd [belong [I] ++; int Index = head [I]; for (; index; Index = E [Index]. next) {J = E [Index]. v; If (belong [I]! = Belong [J]) {chu [belong [I] ++; Ru [belong [J] ++ ;}__ int64 Sheng = 1; sheng = Sheng * n * (n-1); Sheng = Sheng-M ;__ int64 Xiao = 0x7fffffffffffff ;__ int64 TEM; for (I = 1; I <= ret; ++ I) {If (chu [I] = 0 | Ru [I] = 0) {TEM = (_ int64) numd [I]) * (N-numd [I]); If (TEM <Xiao) {Xiao = TEM ;}}} Sheng = Sheng-Xiao; printf ("case % d: % i64d \ n ", Ti, Sheng);} return 0 ;}