|
#include <iostream> using namespace std; #define init(I) memset(I,0,sizeof(I)) const int maxn=101; struct edge { int data; edge *next; }; edge *g1[maxn],*g2[maxn],*g[maxn]; int vis[maxn],path[maxn],scc[maxn],mark[maxn][maxn]; int out[maxn],in[maxn]; int n,m,cnt;
void add(edge* t[],int s,int e){ edge *p; p=new edge; p->data=e; p->next=t[s]; t[s]=p; }
void dfs1(int s){ vis[s]=1; edge *p; for(p=g1[s];p;p=p->next) if(!vis[p->data]) dfs1(p->data); path[0]++; path[path[0]]=s; }
void dfs2(int s){ vis[s]=1; scc[s]=scc[0]; edge *p; for(p=g2[s];p;p=p->next) if(!vis[p->data]) dfs2(p->data); }
void shrink(){ int s,e,k; init(mark); edge *p; for(k=1;k<=n;k++) for(p=g1[k],s=scc[k];p;p=p->next) { e=scc[p->data]; if(s!=e&&!mark[s][e]) { mark[s][e]=1; add(g,s,e); } } }
void kosaraju() { int i; path[0]=scc[0]=0; init(vis); for(i=1;i<=n;i++) if(!vis[i]) dfs1(i); init(vis); for(i=n;i>=1;i--) { if(!vis[path[i]]) { scc[0]++; dfs2(path[i]); } } } int main() { int to,i,j; scanf("%d",&n); for(i=1;i<=n;i++) g1[i]=g2[i]=g[i]=NULL; for(i=1;i<=n;i++) { while(scanf("%d",&to)&&to) { add(g1,i,to); add(g2,to,i); } } kosaraju(); shrink();
init(out); init(in); int cnt=scc[0]; for(i=1;i<=cnt;i++) for(j=1;j<=cnt;j++) if(mark[i][j]) { out[i]++; in[j]++; } if(cnt==1) { printf("1\n0\n"); return 0; } int t1=0,t2=0; for(i=1;i<=cnt;i++) { if(in[i]==0) t1++; if(out[i]==0) t2++; } printf("%d\n",t1); printf("%d\n",t1>t2?t1:t2); return 0; }
|