Files
python/TangDou/AcWing/SCC/367.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

79 lines
1.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
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;
}