Раздел «Алгоритмы».ArticulationPointsCPP:

Поиск точек раздела: реализация на C++

Код

/*
 * Поиск точек раздела в неориентированном графе.
 * Даниил Швед, 2008. МФТИ.
 * mailto: danshved [no-spam] gmail.com
 */
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;

typedef vector<int> VInt;
typedef vector<VInt> VVInt;
typedef VInt::iterator VIter;
typedef vector<bool> VBool;

VVInt graph;
VInt colors, enter, leave, low, parents;
int myTime = 0;
VBool articulation;

/*
 * Поиск в глубину, вычисление функций enter. leave и low,
 * и здесь же определение точек раздела
 */
void visit(int u) {
   int childrenCount = 0;
   colors[u] = 1;
   low[u] = enter[u] = ++myTime;
   
   for(VIter it = graph[u].begin(); it != graph[u].end(); it++)
      if(colors[*it] == 0) {
         parents[*it] = u;
         visit(*it);
         low[u] = min(low[u], low[*it]);
         
         if(parents[u] != -1 && low[*it] >= enter[u])
            articulation[u] = true;
         childrenCount++;
      } else if(colors[*it] == 1 && *it != parents[u]) {
         low[u] = min(low[u], enter[*it]);
      }
   
   if(parents[u] == -1)
      articulation[u] = (childrenCount >= 2);
   
   colors[u] = 2;
   leave[u] = ++myTime;
}

/*
 * Во входном потоке: числа n и m, затем m описаний ребер.
 * В выходном потоке: номера точке раздела
 */
int main() {
   int n, m, i;
   
   // Считаем граф
   scanf("%d%d", &n, &m);
   graph.resize(n);
   while(m--) {
      int from, to;
      scanf("%d%d", &from, &to);
      graph[from - 1].push_back(to - 1);
      graph[to - 1].push_back(from - 1);
   }
   
   // Запустим поиск в глубину
   colors.assign(n, 0);
   enter.resize(n);
   leave.resize(n);
   low.resize(n);
   parents.assign(n, -1);
   articulation.assign(n, false);
   for(i = 0; i < n; i++)
      if(colors[i] == 0)
         visit(i);
         
   // Выведем список точек раздела
   for(i = 0; i < n; i++)
      if(articulation[i])
         printf("%d ", i + 1);
   printf("\n");
   
   return 0;
}

Ссылки

-- DanielShved - 27 Mar 2008