Найдите компонент сильной связи ориентированного графа и краткое изложение алгоритма Tarjan.

Что такое сильный компонент связи

В ориентированном графе:

1. Если две точки могут быть соединены друг с другом через направленное ребро, то эти две точки называются сильной связью ;

2. Если любые две точки в графе сильно связаны, то ориентированный граф называется сильно связным графом (точка также является сильно связным графом);

3. Очень большой подграф с сильной связью в графе с несильной связью (не включаемый в другой более крупный подграф с сильной связью ) называется компонентой сильной связности этого графа .

Как показано на рисунке:

Компоненты сильной связности в графе: {1,2,4} и {3}.

Видно, что сильно связанные компоненты имеют несколько очевидных характеристик:

1. В каждой сильно связной компоненте не будет повторяющихся точек.

2. В сильно связном компоненте любая точка u может пройти через все точки через направленное ребро и, наконец, вернуться в точку u.

Что такое тарджан

Из сделанных выше выводов видно, что сильно связная компонента является максимально направленным кольцом.

Так называемый tarjan должен быть связан с DFS (не спрашивайте меня, почему). Предположим, что начиная с точки u DFS, если u находится в сильно связном компоненте, то в конце обязательно вернется в точку u.

Конкретная реализация алгоритма tarjan:

1. Используйте dfn [u], чтобы записать поисковый номер u (указывая, что u - это искомая точка);

2. Используйте low [u], чтобы представить точку с наименьшим поисковым номером, который можно найти вниз от u, и инициализируйте low [u] как dfn [u];

3. Поместите u в стек, и точки на станции представляют точки, которые не были классифицированы как сильно связанные компоненты;

4. Перечислите точки, соединенные u, выполните поиск вниз и установите эту точку как v. Если v находится в стеке, то есть v был найден и не классифицирован как компонент с сильной связью, тогда low [u] = min (low [u], dfn [v]); если v не был найден, то v не должен классифицироваться как сильно связный компонент, тогда DFS [v] и record low [u] = min (low [u], low [v]);

5. Наконец, если dfn [u] равно low [u], это означает, что поиск вниз от u вернется к u (или поиск вниз от u), потому что в стеке точка ищется вниз от u. все сложены на u, поэтому точки, сложенные на u в стопке, выталкиваются из стопки с u и классифицируются как сильно связный компонент.

Среди всех точек, найденных u, точка, которую нельзя вернуть в u через направленное ребро (она не может быть сильно связана с u), или она соединена с точкой v с большим значением dfn, чем u, образуя небольшое кольцо , а затем извлекается из стека ;

Либо кольцо не сформировано, низкое значение остается таким же, как значение dfn, и оно будет вытолкнуто из стека (это компонент сильной связи точки),

Следовательно, все остальные точки в стеке на u - это точки, которые могут быть сильно связаны с u.

Например, картинка выше:

Искать из точки 1:

Искать вниз от 2 до 4:

4 соединяется с 1, обнаруживается, что 1 находится в стеке, меняется низкий уровень и возвращается к 2:

Далее ищите от 2 до 3:

3 Невозможно снова выполнить поиск, dfn = low, выскакивает из стека:

Наконец, вернувшись к 1, обнаруживаем, что dfn = low, 1, 2 и 4 выскакивают из стека вместе:

Найдите 2 компоненты сильной связности: {3}, {1,2,4}.

основной код tarjan

void tarjan(int x){
	dfn[x]=low[x]=IN++;
	in_s[x]=1;
	S.push(x);
	for(int i=0;i<G[x].size();i++){
		if(!dfn[G[x][i]]){
			tarjan(G[x][i]);
			low[x]=min(low[x],low[G[x][i]]);
		}
		else if(in_s[G[x][i]])low[x]=min(low[x],dfn[G[x][i]]);
	}
	if(dfn[x]==low[x]){
		num++;int v;
		do{
			v=S.top();
			S.pop();
			belong[v]=num;
			M[num]=min(M[num],mn[v]);
			in_s[v]=0;
		}while(v!=x);
	}
}

 

 

рекомендация

отblog.csdn.net/weixin_43960287/article/details/90715320