好久没写过图论了,练练手~
code:
#include <bits/stdc++.h> #define N 10005 #define M 5000090 #define setIO(s) freopen(s".in","r",stdin) using namespace std; stack<int>S; int edges,n,cnt,tot; int hd[N],to[M],nex[M],dfn[N],low[N],id[N],in[N],out[N],size[N]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void tarjan(int x) { dfn[x]=low[x]=++cnt,S.push(x); for(int i=hd[x];i;i=nex[i]) { int v=to[i]; if(!dfn[v]) tarjan(v), low[x]=min(low[x], low[v]); else if(!id[v]) low[x]=min(low[x], dfn[v]); } if(low[x]==dfn[x]) { ++tot; for(;;) { int u=S.top(); S.pop(); id[u]=tot; if(u==x) break; } } } int main() { int i,j,x; // setIO("input"); scanf("%d",&n); for(i=1;i<=n;++i) for(scanf("%d",&x);x!=0;scanf("%d",&x)) add(i,x); for(i=1;i<=n;++i) if(!dfn[i]) tarjan(i); for(i=1;i<=n;++i) { for(j=hd[i];j;j=nex[j]) if(id[i]!=id[to[j]]) ++out[id[i]], ++in[id[to[j]]]; } int a=0,b=0; for(i=1;i<=tot;++i) a+=in[i]==0, b+=out[i]==0; printf("%d %d ",a,max(a,b)); return 0; }