#include using namespace std; const int N = 110, M = 10010; int n; int dfn[N], low[N], ts; int stk[N], top; int in_stk[N]; int id[N], scc_cnt; int din[N], dout[N]; // 链式前向星 int e[M], h[N], idx, w[M], ne[M]; void add(int a, int b, int c = 0) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } // Tarjan算法求强连通分量 void tarjan(int u) { dfn[u] = low[u] = ++ts; stk[++top] = u; in_stk[u] = 1; for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if (in_stk[v]) low[u] = min(low[u], dfn[v]); } if (dfn[u] == low[u]) { ++scc_cnt; int x; do { x = stk[top--]; in_stk[x] = 0; id[x] = scc_cnt; } while (x != u); } } int main() { scanf("%d", &n); memset(h, -1, sizeof h); for (int i = 1; i <= n; i++) { int c; while (scanf("%d", &c), c) add(i, c); // i支援t } for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i); // 统计缩点后的DAG,此DAG中出度为0、入度为0的点的个数 for (int u = 1; u <= n; u++) for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; int a = id[u], b = id[v]; if (a != b) dout[a]++, din[b]++; } int a = 0, b = 0; for (int i = 1; i <= scc_cnt; i++) { if (!din[i]) a++; // 入度为0的强连通块 if (!dout[i]) b++; // 出度为0的强连通块 } // 输出入度为0的连通块数量,也就是需要软件的数量 printf("%d\n", a); if (scc_cnt == 1) // 如果只有一个强连通块,不用连边 puts("0"); else printf("%d\n", max(a, b)); // 输出入度为0与出度为0的连通块最大值 return 0; }