Tarjan
There is a Tarjan can find connected components algorithm to strengthen the country, it can do the linear time complexity.
Remember first of two key arrays before learning:
Low [i] represents the elements in the stack reach the minimum position i (i.e. closest to the bottom of the stack);
DFN [i] denotes the i element during traversal numeral (dfs is traversed to traverse the first few);
This algorithm think understood that when the key is dfn [i] == when low [i], i elements in the stack are later strongly connected components (strongly connected components may also be referred subgraph);
Can start did not point out the beginning of understanding, such as Point 3, dfn this point [3] = 3, low [ 3] = 3, and will not traverse down, i.e. points 3 and dfn low change will no longer be described dfn [3] == low [3 ], point 3 is a single strongly connected components;
and various other points (except One point), while the beginning of their low = = dfn, but then it will change until the number one spot;
Turning back to why when i push back the elements are strongly connected component, you can think, i and i are the elements behind connected (it can be said i can reach them), when i can own yourself, that i can not point to reach i can do?
template:
void Tarjan ( int x ) {
dfn[ x ] = ++dfs_num ;
low[ x ] = dfs_num ;
vis [ x ] = true ;//是否在栈中
stack [ ++top ] = x ;
for ( int i=head[ x ] ; i!=0 ; i=e[i].next ){
int temp = e[ i ].to ;
if ( !dfn[ temp ] ){
Tarjan ( temp ) ;
low[ x ] = gmin ( low[ x ] , low[ temp ] ) ;
}
else if ( vis[ temp ])low[ x ] = gmin ( low[ x ] , dfn[ temp ] ) ;
}
if ( dfn[ x ]==low[ x ] ) {//构成强连通分量
vis[ x ] = false ;
color[ x ] = ++col_num ;//染色
while ( stack[ top ] != x ) {//清空
color [stack[ top ]] = col_num ;
vis [ stack[ top-- ] ] = false ;
}
top -- ;
}
}
On a template question:
This question as long as the recording is larger than the smallest ring of ring 2 (strongly connected subgraph) is;
Code:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=200100;
const int M=1000100;
const LL mod=100000000;
int dfn[N],low[N],sta[N],tot,head[N],cnt,ans=2e9,top;
bool vis[N];
struct Node{
int to,nex;
}edge[N*2];
void add(int p,int q){
edge[cnt].to=q;
edge[cnt].nex=head[p];
head[p]=cnt++;
}
void Tarjan(int p){
dfn[p]=++tot,low[p]=tot;
if(!vis[p]) vis[p]=true,sta[++top]=p;
for(int i=head[p];~i;i=edge[i].nex){
int q=edge[i].to;
if(!dfn[q]){
Tarjan(q);
low[p]=min(low[p],low[q]);
}
else if(vis[q]) low[p]=min(low[p],dfn[q]);
}
if(dfn[p]==low[p]){
int sum=1;
vis[p]=false;
while(sta[top]!=p){
vis[sta[top]]=false;
sum++;
top--;
}
top--;
if(sum>1) ans=min(ans,sum);
}
}
int main(){
memset(head,-1,sizeof(head));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int t;
scanf("%d",&t);
add(i,t);
}
for(int i=1;i<=n;i++){
if(!dfn[i]) Tarjan(i);
}
cout<<ans<<endl;
return 0;
}