http://poj.org/problem?id=1236 #include <iostream> #include <string.h> #include <stack> #define MAX 101 using namespace std; int n,g[MAX][MAX],tmp,in[MAX],out[MAX]; int dfn[MAX],low[MAX],index=1,cnt=0,belong[MAX]; bool instack[MAX]; stack<int> Q; int min(int a,int b) { return a<b?a:b; } int max(int a,int b) { return a>b?a:b; } void init() { memset(g,0,sizeof(g)); memset(instack,false,sizeof(instack)); cin>>n; for (int i=1;i<=n;i++)//建图 while (1) { cin>>tmp; if (tmp==0) break; g[i][tmp]=true; } } void tarjan(int x)//求连通分支 { dfn[x]=low[x]=index; index++; Q.push(x); instack[x]=true; for (int i=1;i<=n;i++) { if (!g[x][i]) continue; if (!dfn[i]) { tarjan(i); low[x]=min(low[x],low[i]); } else if (instack[i]) low[x]=min(low[x],dfn[i]); } if (low[x]==dfn[x]) { cnt++; while (1) { tmp=Q.top(); Q.pop(); belong[tmp]=cnt; instack[tmp]=false; if (tmp==x) break; } } } void q2() { int ans1=0,ans2=0,i,j; for (i=1;i<=n;i++) for (j=1;j<=n;j++) //对于强连通分支缩点,并算出入度与出度 { if (!g[i][j]) continue; if (belong[i]!=belong[j]) { in[belong[j]]++; out[belong[i]]++; } } for (i=1;i<=cnt;i++) { if (!in[i]) ans1++; if (!out[i]) ans2++; } if (cnt==1) cout<<1<<endl<<0<<endl; else cout<<ans1<<endl<<max(ans1,ans2)<<endl; } void display() { init(); for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); q2(); } int main() { // freopen("in.txt","r",stdin); display(); return 0; }