题目
求入度为0的强连通分量和出度为0的强连通分量。
分析
用kosaraju,再求每个强连通分量的入度和出度。
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
int n,m,ans,x,f[101],inn,oun,ind[101],in[101],out[101]; bool v[101],a[101][101];
int ing(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void dfs1(int x){
v[x]=1;
for (int i=1;i<=n;i++)
if (a[x][i]&&!v[i]) dfs1(i);
f[++m]=x;
}
void dfs2(int x){
v[x]=1; ind[x]=ans;
for (int i=1;i<=n;i++)
if (a[i][x]&&!v[i]) dfs2(i);
}
void kosaraju(){
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (a[i][j]&&ind[i]!=ind[j]){//两点连通且不属于同一个连通图
in[ind[j]]++;//入度
out[ind[i]]++;//出度
}
for (int i=1;i<=ans;i++) inn+=(!in[i]),oun+=(!out[i]);//入度为0,出度为0
printf("%d\n%d",inn,max(inn,oun));
}
int main(){
n=ing();
for (int i=1;i<=n;i++) while (x=ing(),x) a[i][x]=1;
for (int i=1;i<=n;i++) if (!v[i]) dfs1(i); memset(v,0,sizeof(v));
for (int i=m;i>=1;i--) if (!v[f[i]]) ans++,dfs2(f[i]); memset(v,0,sizeof(v));
if (ans==1) printf("1\n0");//说明强连通分量的出度为0
else kosaraju();
return 0;
}