模板对应POJ1236
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m, head[N], cnt, sum, visit[N];
struct go{
int e, next;
}edge[N * N];
void addedge(int a, int b){
edge[cnt].e = b;
edge[cnt].next = head[a];
head[a] = cnt++;
}
/********************Tarjan********************/
int dfn[N], low[N], idx, a, scc[N];
int vis[N], stack[N], tot;
int tarjanDFS(int to){
vis[to] = 1;
stack[++idx] = to;
low[to] = dfn[to] = ++a;
for(int it = head[to];it != -1;it = edge[it].next){
int end = edge[it].e;
if(!vis[end]){
tarjanDFS(end);
low[to] = min(low[to], low[end]);
}
if(vis[end] == 1)
low[to] = min(dfn[end], low[to]);
}
if(dfn[to] == low[to]){
tot++;
int e;
do{
e = stack[idx--];
scc[e] = tot;
vis[e] = 2;
}while(e != to);
}
}
int tarjan(int n){
idx = 0, tot = 0, a = 0;
memset(vis, 0, sizeof(vis));
memset(dfn, 0, sizeof(dfn));
for(int i = 1;i <= n;i++)
if(!vis[i])
tarjanDFS(i);
return tot;
}
/*********************END**********************/
void solve(){
int i, it, inde[N], outde[N];
memset(inde, 0, sizeof(inde));
memset(outde, 0, sizeof(outde));
memset(visit, 0, sizeof(visit));
tarjan(n);
vector<int> v[N];
for(i = 1;i <= n;i++)
for(it = head[i];it != -1;it = edge[it].next){
int end = edge[it].e;
if(scc[i] != scc[end]){
v[scc[i]].push_back(scc[end]);
inde[scc[end]]++;
outde[scc[i]]++;
}
}
int res = 0, son = 0;
for(i = 1;i <= tot;i++){
if(outde[i] == 0)
son++;
if(inde[i] == 0)
res++;
}
cout << res << endl;
if(tot == 1){
cout << 0 << endl;
return ;
}
cout << max(son, res) << endl;
return ;
}
int main(){
while(~scanf("%d", &n)){
int i, a;
cnt = 0;
memset(head, -1, sizeof(head));
for(i = 1;i <= n;i++){
while(scanf("%d", &a)&&a)
addedge(i, a);
}
solve();
}
return 0;
}