119 lines
1.4 KiB
C++
119 lines
1.4 KiB
C++
#include <iostream>
|
|
#include<cstdio>
|
|
#include<algorithm>
|
|
#include <cmath>
|
|
using namespace std;
|
|
const int N=105,NN=N*N;
|
|
int n;
|
|
int ne[NN],to[NN],h[N];
|
|
int cnt=0;
|
|
int dfn[N],low[N];
|
|
bool in[N];
|
|
int dep=0;
|
|
int s[N];//stack
|
|
int top=0;
|
|
int belong[N];
|
|
int id=0;
|
|
bool fa[N],son[N];
|
|
//void init(int n)
|
|
//{
|
|
//
|
|
//}
|
|
void add(int u,int v)
|
|
{
|
|
ne[++cnt]=h[u];
|
|
to[cnt]=v;
|
|
h[u]=cnt;
|
|
}
|
|
void targan(int u)
|
|
{
|
|
dfn[u]=++dep;
|
|
low[u]=dep;
|
|
in[u]=1;
|
|
int v;
|
|
s[++top]=u;
|
|
for(int i=h[u];i;i=ne[i])
|
|
{
|
|
v=to[i];
|
|
if(!dfn[v])
|
|
{
|
|
targan(v);
|
|
low[u]=low[u]<low[v]? low[u]:low[v];
|
|
}
|
|
else if(in[v])
|
|
{
|
|
low[u]=low[u]<low[v]? low[u]:low[v];
|
|
}
|
|
}
|
|
if(dfn[u]==low[u])
|
|
{
|
|
id++;
|
|
// printf("%d:%d ",u,id);
|
|
do
|
|
{
|
|
belong[s[top]]=id;
|
|
in[s[top]]=0;
|
|
}while(s[top--]!=u);//-- ->++
|
|
}
|
|
}
|
|
void ce()
|
|
{
|
|
for(int i=1;i<=n;i++)
|
|
{
|
|
printf("%d(%d) ",i,belong[i]);
|
|
}
|
|
}
|
|
int main()
|
|
{
|
|
scanf("%d",&n);
|
|
// init(n);
|
|
int v;
|
|
for(int i=1; i<=n; i++)
|
|
{
|
|
while(~scanf("%d",&v)&&v)
|
|
{
|
|
add(i,v);
|
|
}
|
|
}
|
|
for(int i=1;i<=n;i++)
|
|
{
|
|
if(!dfn[i])
|
|
{
|
|
targan(i);
|
|
}
|
|
}
|
|
// ce();
|
|
for(int i=1;i<=n;i++)
|
|
{
|
|
for(int j=h[i];j;j=ne[j])
|
|
{
|
|
v=to[j];
|
|
if(belong[i]!=belong[v])//v->j
|
|
{
|
|
fa[belong[v]]=1;
|
|
son[belong[i]]=1;
|
|
}
|
|
}
|
|
}
|
|
int res1=0,res2=0;
|
|
for(int i=1;i<=id;i++)
|
|
{
|
|
// printf("%d(%d,%d) ",i,fa[i],son[i]);
|
|
if(!fa[i])
|
|
{
|
|
res1++;
|
|
}
|
|
if(!son[i])
|
|
{
|
|
res2++;
|
|
}
|
|
}
|
|
res2=res1>res2? res1:res2;
|
|
if(id==1)
|
|
{
|
|
res1=1;res2=0;
|
|
}
|
|
printf("%d\n%d",res1,res2);
|
|
return 0;
|
|
}
|