【NOIP2015】信息传递
tarjan模板题,求最小的强连通分量
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
const int maxx=2e5+5;
vector<int>E[maxx];
int dfn[maxx],low[maxx],tot,n,ans=0x3f3f3f3f,vis[maxx];
stack<int>S;
void tarjan(int x){
low[x]=dfn[x]=++tot;
vis[x]=1;
S.push(x);
for(int i=0;i<E[x].size();i++){
int v=E[x][i];
if(!dfn[v]){
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(vis[v]){
low[x]=min(low[x],dfn[v]);
}
}
if(low[x]==dfn[x]){
int cnt=0;
while(1){
int now=S.top();
S.pop();
cnt++;
if(now==x)break;
}
if(cnt>1){//连通分量为1的不用管
ans=min(ans,cnt);
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
E[i].push_back(x);//邻接表
}
for(int i=1;i<=n;i++){
if(!dfn[i]){//从没有访问到的点开始访问
tarjan(i);
}
}
cout<<ans<<endl;
return 0;
}