Tarjan algorithm study notes

Tarjan

There is a Tarjan can find connected components algorithm to strengthen the country, it can do the linear time complexity.

Learning blog

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);

Here Insert Picture Description
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:

Luo Gu P2661 messaging

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;
}
Published 264 original articles · won praise 46 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_44291254/article/details/104933379