#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Edge {
int u, v, next;
} edge[100010];
int n, m, num = 0, in[100010], out[100010], head[100010];
int top = 0, cnt = 0, index = 0, dfn[50010], low[50010], place[50010], stack[50010];
void add(int u, int v) {
num ++;
edge[num].u = u;
edge[num].v = v;
edge[num].next = head[u];
head[u] = num;
}
void tarjan(int u) {
stack[++ top] = u;
dfn[u] = low[u] = ++ index;
for(int i = head[u]; i; i = edge[i].next) {
int v = edge[i].v;
if(! low[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(! place[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]) {
cnt ++;
while(1) {
int x = stack[top --];
place[x] = cnt;
if(x == u) break;
}
}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
while(scanf("%d", &m) && m)
add(i, m);
for(int i = 1; i <= n; i ++)
if(! place[i]) tarjan(i);
if(cnt == 1) {
printf("1\n0");
return 0;
}
for(int i = 1; i <= num; i ++) {
int u = edge[i].u, v = edge[i].v;
if(place[u] != place[v])
in[place[v]] ++, out[place[u]] ++;
}
int ans1 = 0, ans2 = 0;
for(int i = 1; i <= cnt; i ++) {
if(! in[i]) ans1 ++;
if(! out[i]) ans2 ++;
}
printf("%d\n%d", ans1, max(ans1, ans2));
return 0;
}
【NOIP模板】 tarjan
最新推荐文章于 2022-11-24 08:57:02 发布