Краткое описание алгоритма поиска в ширину
Алгоритм ищет кратчайший путь, и его длину от заданной вершины до всех остальных. При этом просматривается последовательно каждый уровень соседей стартовой вершины. То есть мы в прямом смысле ходим в ширину по всему уровню. Подробнее вы всегда можете почитать на википедии. А вообще, если вы ищете реализацию, то уже знаете сам алгоритм, так что погнали реализовывать поиск в ширину!
Моя реализация поиска в ширину на c++
Граф представлен следующим образом. Массив(vector c++) из n элементов, где n — число вершин в графе. Каждый элемент массива соответствует вершине графа и содержит вложенный массив — список вершин, смежных с данной.
typedef vector< vector<int> > graphNotWeighted;
Функция реализации принимает на вход сам граф и номер стартовой вершины, отрабатывает, и заполняет два массива: массив расстояний от каждой вершины до стартовой, и массив предков каждой вершины на пути к стартовой. С помощью второго массива восстанавливается полный путь от стартовой вершины до всех остальных.
Исходный код алгоритма поиска в ширину на c++
void BFS(graphNotWeighted &G, int start) {
queue<int> Q;
//distance[i] - расстояние от i-ой вершины до стартовой
vector<int> distance(G.size(), -1);
//prevTop[i] - предок i-ой вершины в кратчайшем пути
vector<int> prevTop(G.size(), -1);
distance[start] = 0;
Q.push(start);
while (Q.size()) {
int u = Q.front();
Q.pop();
for (int j = 0; j < G[u].size(); j++) {
int v = G[u][j];
if (distance[v] == -1) {
distance[v] = distance[u] + 1;
prevTop[v] = u;
Q.push(v);
}
}
}
//print results
for (int i = 0; i < prevTop.size(); i++) {
cout << i << '(' << distance[i] << ")\t:";
int x = prevTop[i];
while (x != -1) {
cout << x << ' ';
x = prevTop[x];
}
cout << endl;
}
return;
}
Задачи, решаемые с помощью поиска в ширину
Проверка графа на связность
Выполняется проще простого. Инициализируем массив distance и смотрим от всех ли вершин можно добраться до стартовой. Если хотя бы от одной вершины путь отсутствует — граф несвязен.
bool isConnected(graphNotWeighted &G, int start) {
queue<int> Q;
vector<int> distance(G.size(), -1);
vector<int> prevTop(G.size(), -1);
distance[start] = 0;
Q.push(start);
while (Q.size()) {
int u = Q.front();
Q.pop();
for (int j = 0; j < G[u].size(); j++) {
int v = G[u][j];
if (distance[v] == -1) {
distance[v] = distance[u] + 1;
prevTop[v] = u;
Q.push(v);
}
}
}
//print results
for (int i = 0; i < G.size(); ++i)
if (distance[i] == -1)
return false;
return true;
}
Подсчет количества компонент связности графа
Смысл в том, что после вызова процедуры BFS для вершины i , в массиве distance будут инициализированы все вершины из ее компоненты. Вызывая процедуру для каждой вершины, мы найдем все возможные компоненты связности.
unsigned int connectedComponentsCount(graphNotWeighted &G) {
queue<int> Q;
vector<int> distance(G.size(), -1);
vector<int> prevTop(G.size(), -1);
unsigned int count = 0;
for(int start = 0; start < G.size(); start++) {
if(distance[start] == -1) {
distance[start] = 0;
Q.push(start);
while (Q.size()) {
int u = Q.front();
Q.pop();
for (int j = 0; j < G[u].size(); j++) {
int v = G[u][j];
if (distance[v] == -1) {
distance[v] = distance[u] + 1;
prevTop[v] = u;
Q.push(v);
}
}
}
count++;
}
}
return count;
}