#8 WA
问题:缩点后出现一个入度、出度皆为0的点被统计入答案。
#include<bits/stdc++.h>
#define find fir
using namespace std;
int n,st[105],top;
int find[105],tot;
int rd[105],cd[105];
int num,colorn,dfn[105],low[105],color[105];
struct node{
int to,nxt;
}e[10005];
void add_edge(int u,int v)
{
e[++tot].to=v;
e[tot].nxt=find[u];
find[u]=tot;
}
void tarjan(int u)
{
dfn[u]=low[u]=num++;
st[++top]=u;
for(int i=find[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!color[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
color[u]=++colorn;
while(st[top]!=u)
{
color[st[top]]=colorn;
top--;
}
top--;
}
}
void calc()
{
for(int i=1;i<=n;i++)
{
for(int j=find[i];j;j=e[j].nxt)
{
if(color[i]!=color[e[j].to])
{
cd[color[i]]++;
rd[color[e[j].to]]++;
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int j;
while(cin>>j)
{
if(j==0) break;
add_edge(i,j);
}
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
calc();
int ans1=0,ans2=0;
//for(int i=1;i<=n;i++) cout<<i<<" "<<color[i]<<endl;
//cout<<endl;
for(int i=1;i<=colorn;i++)
{
//cout<<i<<" "<<rd[i]<<" "<<cd[i]<<endl;
if(rd[i]==0) ans1++;
if(cd[i]==0) ans2++;
}
ans2=max(ans1,ans2);
if(colorn!=1) printf("%d\n%d",ans1,ans2);
else printf("%d\n0",ans1);
return 0;
}
正确答案: 6 3
我的输出: 7 4