tarjan缩点的模板题
#include<bits/stdc++.h> using namespace std; const int N=2e5+10; int id[N]; int h[N],ne[N],w[N],e[N],idx; stack<int> q; int scnt; int cnt[N]; int times; int n,m; int dfn[N],low[N]; int ins[N]; int in[N]; int out[N]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void tarjan(int u){ dfn[u]=low[u]=++times; q.push(u); ins[u]=1; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(!dfn[j]){ tarjan(j); low[u]=min(low[u],low[j]); } else if(ins[j]){ low[u]=min(low[u],dfn[j]); } } if(dfn[u]==low[u]){ ++scnt; while(1){ int t=q.top(); q.pop(),ins[t]=0; id[t]=scnt; cnt[scnt]++; if(t==u) break; } } } int main(){ int i; cin>>n; memset(h,-1,sizeof h); for(i=1;i<=n;i++){ int x; while(cin>>x,x){ add(i,x); } } for(i=1;i<=n;i++){ if(!dfn[i]) tarjan(i); } int j; for(i=1;i<=n;i++){ for(j=h[i];j!=-1;j=ne[j]){ int k=e[j]; if(id[i]!=id[k]){ in[id[i]]++; out[id[k]]++; } } } int zero=0; int sign=0; for(i=1;i<=scnt;i++){ if(!in[i]){ zero++; } if(!out[i]){ sign++; } } cout<<sign<<endl; if(scnt==1) cout<<0<<endl; else cout<<max(zero,sign)<<endl; }View Code