Some schools are connected over the Internet. Each school has a list, that is, the points it points. The list of school A contains school B, and it cannot be guaranteed that the list of school B contains school. There is a software. 1. Ask at least a few schools to ensure that all schools can obtain the software. 2. add at least a few sides to send the software to a school, and all other schools can get the software.
Question: The first question is the point where the inbound degree is 0. The second question is how to add several sides to change the graph to a strongly connected graph.
PS: For a directed acyclic graph, all the points whose inbound degree is not 0 can be obtained from a point whose inbound degree is 0. (Because of the absence of loops, it is inevitable that you go back from any point with an indegree of 0 to a point with an indegree of 0)
# Include <iostream> using namespace STD; # define n 500 # define min (a, B) (a <B? A: B) # define max (A, B) (A> B? A: B) int N, ans1, ans2; int size, CNT, top, ID; int instack [N], stack [N]; int head [N], low [N], dfn [N]; int in [N], out [N], block [N]; struct edge {int V, next ;} edge [N * 20]; void Tarjan (int u) {int V; instack [u] = 1; stack [++ top] = u; dfn [u] = low [u] = ++ ID; For (INT I = head [u]; I; I = edge [I]. next) {v = edge [I]. v; If (! Dfn [v]) {Tarjan (V); low [u] = min (low [u], low [v]);} else if (instack [v]) low [u] = min (low [u], dfn [v]);} If (low [u] = dfn [u]) {CNT ++; do {v = stack [top --]; instack [v] = 0; block [v] = CNT;} while (u! = V) ;}} void shrink () {int U, V, I; for (u = 1; U <= N; U ++) {for (I = head [u]; I; I = edge [I]. next) {v = edge [I]. v; If (Block [u]! = Block [v]) {out [block [u] ++; in [block [v] ++ ;}} int T1 = 0, T2 = 0; for (I = 1; I <= CNT; I ++) {If (in [I] = 0) T1 ++; If (out [I] = 0) t2 ++;} If (CNT = 1) // when the graph itself is a strongly connected graph !!! {Ans1 = 1; ans2 = 0;} else {ans1 = T1; ans2 = max (T1, T2) ;}} void initial () {size = CNT = id = Top = 0; For (INT I = 1; I <= N; I ++) {In [I] = out [I] = block [I] = head [I] = 0; instack [I] = dfn [I] = low [I] = 0 ;}} void add (INT U, int v) {size ++; edge [size]. V = V; edge [size]. next = head [u]; head [u] = size;} int main () {initial (); scanf ("% d", & N); int V, I; for (I = 1; I <= N; I ++) while (scanf ("% d", & V) Dd (I, V); for (I = 1; I <= N; I ++) if (! Dfn [I]) Tarjan (I); shrink (); // click it to calculate the inbound and outbound values of the block. Printf ("% d \ n", ans1, ans2); Return 0 ;}