#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#define LL long long
using namespace std;
const int inf=0x3f3f3f3f;
const double eps=10e-10;
const int maxn=100+2;
const int maxm=100*100+2;
struct Edge { int v,next; };
Edge e[maxm];
int head[maxn],tot,dfs_clock,tot2,sccno[maxn],in[maxn],out[maxn],pre[maxn];
vector<int> scc_block[maxn];
int n;
stack<int> S;
void addedge(int u,int v)
{
e[tot].v=v; e[tot].next=head[u];
head[u]=tot++;
}
int find_scc(int u)
{
int lowu;
pre[u]=lowu=++dfs_clock;
S.push(u);
int i,tem;
for(i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(!pre[v])
{
int lowv=find_scc(v);
lowu=min(lowu,lowv);
}
else if(!sccno[v])
lowu=min(lowu,pre[v]);
}
if(lowu==pre[u])
{
++tot2;
for(;;)
{
tem=S.top(); S.pop();
scc_block[tot2].push_back(tem);
sccno[tem]=tot2;
if(tem==u) break;
}
}
return lowu;
}
int main()
{
cin>>n;
int i,j,tem;
tot=0;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)
while(scanf("%d",&tem)&&tem) addedge(i,tem);
tot2=0;
for(i=1;i<=n;i++) if(!pre[i])
{
dfs_clock=0;
find_scc(i);
}
for(i=1;i<=tot2;i++) in[i]=out[i]=1;
int v;
for(i=1;i<=n;i++)
{
for(j=head[i];j!=-1;j=e[j].next)
{
v=e[j].v;
if(sccno[i]!=sccno[v]) in[sccno[v]]=out[sccno[i]]=0;
}
}
int in0=0,out0=0;
int ans1=0,ans2=0;
for(i=1;i<=tot2;i++)
{
if(in[i]) { in0++; ans1++; }
if(out[i]) out0++;
}
if(tot2==1) ans2=0;
else ans2=max(in0,out0);
printf("%d\n",ans1);
printf("%d\n",ans2);
return 0;
}
强连通分量模板
最新推荐文章于 2022-06-26 23:08:13 发布