notas de estudio del algoritmo de Tarjan

Tarjan

Hay una Tarjan puede encontrar componentes conectados algoritmo para fortalecer el país, que puede hacer la complejidad del tiempo lineal.

Aprender el blog

Recuerde primero de los dos conjuntos de claves antes de aprender:

Baja [i] representa los elementos en la pila alcanzan la posición mínima i (es decir, más cerca de la parte inferior de la pila);

DFN [i] denota el elemento i durante el recorrido numeral (DFS es atravesado para atravesar la primera pocos);

Este algoritmo piense entiende que cuando la llave está dfn [i] == cuando bajo componentes [i], i elementos en la pila son posteriormente fuertemente conectados (componentes fuertemente conectados también puede ser denominado subgrafo);

Aquí Insertar imagen Descripción
Se puede iniciar no señalar el comienzo de la comprensión, tales como el punto 3, DFN este punto [3] = 3, bajo [ 3] = 3, y no va a atravesar hacia abajo, es decir, puntos 3 y DFN bajo el cambio ya no se describe dfn [3] == bajo [3 ], punto 3 es un solo componente fuertemente conexo;
y varios otros puntos (excepto un punto), mientras que el comienzo de sus bajos = = dfn, pero entonces se cambiará hasta que el número uno;

Volviendo a qué componente cuando empujo hacia atrás los elementos están fuertemente conectados, se puede pensar, i e i son los elementos detrás conectada (se puede decir que puedo llegar a ellos), cuando puedo poseer a sí mismo, que no puedo señalar a llegar a lo que puedo hacer?

plantilla:

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

En una pregunta plantilla:

mensajería Luo Gu P2661

Esta pregunta siempre que la grabación es mayor que el anillo más pequeño de anillo de 2 (subgrafo fuertemente conectado) es;

código:

#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;
}
Publicados 264 artículos originales · alabanza won 46 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/qq_44291254/article/details/104933379
Recomendado
Clasificación