E027. Algoritmo поиска компонент связности в grafoе
Источник: e-maxx.ru/algo, страница PDF 88.
Дан неориентированный grafo
с
vertexми и
рёбрами. it is required find в нём все компоненты связности, т. е. разбить вершины grafoа на несколько групп так, что внутри одной группы можно дойти от одной вершины до любой другой, а между разными группами — пути не существует.
Algoritmo решения
Для решения можно воспользоваться как обходом в глубину, так и обходом в ширину. Фактически, мы будем производить серию обходов: сначала запустим обход из первой вершины, и все вершины, которые он при этом обошёл — образуют первую компоненту связности. Затем найдём первую из оставшихся вершин, которые ещё не были посещены, и запустим обход из неё, найдя тем самым вторую компоненту связности. И так далее, пока все вершины не станут помеченными.
Итоговая Asymptotic complexity составит
: в самом деле, такой Algoritmo не будет запускаться от одной и той же вершины дважды, а, значит, каждое edge будет просмотрено ровно два раза (с одного конца и с другого конца).
Implementación
Для реализации чуть более удобным является обход в глубину:
int n;
vector<int> g[MAXN];
bool used[MAXN];
vector<int> comp;
void dfs (int v) {
used[v] = true;
comp.push_back (v);
for (size_t i=0; i<g[v].size(); ++i) {
int to = g[v][i];
if (! used[to])
dfs (to);
} }
void find_comps() {
for (int i=0; i<n; ++i)
used[i] = false;
for (int i=0; i<n; ++i)
if (! used[i]) {
comp.clear();
dfs (i);
cout << "Component:";
for (size_t j=0; j<comp.size(); ++j)
cout << ' ' << comp[j];
cout << endl;
} }
Основная функция для вызова —
, она находит и выводит компоненты связности grafoа. Мы считаем, что grafo задан списками смежности, т.е.
содержит список вершин, в которые есть рёбра из вершины
. Константе
следует задать значение, равное максимально возможному количеству вершин в grafoе.
Вектор
содержит список вершин в текущей компоненте связности.
C# solución
borrador automático, revisar antes de enviarusing System;
using System.Collections.Generic;
using System.Linq;
public static class AlgorithmDraft
{
// Auto-generated C# draft from the original e-maxx C/C++ listing. Review before production use.
int n;
List<int> g[MAXN];
bool[] used = new bool[MAXN];
List<int> comp;
void dfs (int v) {
used[v] = true;
comp.push_back (v);
for (size_t i=0; i<g[v].size(); ++i) {
int to = g[v][i];
if (! used[to])
dfs (to);
}
}
void find_comps() {
for (int i=0; i<n; ++i)
used[i] = false;
for (int i=0; i<n; ++i)
if (! used[i]) {
comp.clear();
dfs (i);
Console.WriteLine( "Component:";
for (size_t j=0; j<comp.size(); ++j)
Console.WriteLine( ' ' << comp[j];
Console.WriteLine( endl;
}
}
}
C++ solución
coincidente/originalint n;
vector<int> g[MAXN];
bool used[MAXN];
vector<int> comp;
void dfs (int v) {
used[v] = true;
comp.push_back (v);
for (size_t i=0; i<g[v].size(); ++i) {
int to = g[v][i];
if (! used[to])
dfs (to);
}
}
void find_comps() {
for (int i=0; i<n; ++i)
used[i] = false;
for (int i=0; i<n; ++i)
if (! used[i]) {
comp.clear();
dfs (i);
cout << "Component:";
for (size_t j=0; j<comp.size(); ++j)
cout << ' ' << comp[j];
cout << endl;
}
}
Java solución
borrador automático, revisar antes de enviarimport java.util.*;
import java.math.*;
public class AlgorithmDraft {
// Auto-generated Java draft from the original e-maxx C/C++ listing. Review before production use.
int n;
ArrayList<Integer> g[MAXN];
boolean used[MAXN];
ArrayList<Integer> comp;
void dfs (int v) {
used[v] = true;
comp.push_back (v);
for (size_t i=0; i<g[v].size(); ++i) {
int to = g[v][i];
if (! used[to])
dfs (to);
}
}
void find_comps() {
for (int i=0; i<n; ++i)
used[i] = false;
for (int i=0; i<n; ++i)
if (! used[i]) {
comp.clear();
dfs (i);
System.out.println( "Component:";
for (size_t j=0; j<comp.size(); ++j)
System.out.println( ' ' << comp[j];
System.out.println( endl;
}
}
}
Материал разбит как Algoritmoическая Tarea: изучить постановку, понять асимптотику и реализовать Algoritmo на выбранном языке.
Vacantes para esta tarea
Se muestran vacantes activas con etiquetas coincidentes.