Find Articulation Points and BridgesΒΆ
Note
Tested on: UVA315, URI1709
#include <cstdio> // scanf, printf
#include <vector> // vector
#include <algorithm> // min
#include <cstring> // memset
#include <set> // set
#include <utility> // pair, make_pair
using namespace std;
#define MAX 110
#define UNVISITED -1
vector<int> G[MAX];
int node_num[MAX]; // memset to -1
int node_low[MAX]; // memset to -1
int parent[MAX]; // memset to -1
int dfs_counter; // start at 0
int dfs_root; // stores the first node visited
int root_children_count; // counts the root children
bool articulations[MAX]; // memset to false; stores the articulations
set< pair<int, int> > bridges; // stores the bridges
void find_articulation_and_bridges_dfs(int node)
{
/*
Find vertices and edges that if deleted the graph becomes
disconnected
!Only works on undirected graphs!
Complexity: O(E + V)
*/
node_num[node] = node_low[node] = dfs_counter++;
for(auto adjacent: G[node])
{
if(node_num[adjacent] == UNVISITED)
{
parent[adjacent] = node;
if(node == dfs_root) root_children_count++;
find_articulation_and_bridges_dfs(adjacent);
if(node_low[adjacent] >= node_num[node]) // Articulation found
articulations[node] = true;
if(node_low[adjacent] > node_num[node]) // Bridge found
bridges.insert(make_pair(node, adjacent));
node_low[node] = min(node_low[node], node_low[adjacent]);
}
// If the adj was already visted and is not a bidirectional
// edge pointing to the node that called the adj
else if(adjacent != parent[node])
node_low[node] = min(node_low[node], node_num[adjacent]);
}
}
void find_articulation_and_bridges(int start_node)
{
/* Setup the variables to use the method */
memset(node_num, UNVISITED, sizeof node_num);
memset(node_low, UNVISITED, sizeof node_low);
memset(parent, UNVISITED, sizeof parent);
memset(articulations, false, sizeof articulations);
bridges.clear();
dfs_counter = root_children_count = 0;
dfs_root = start_node;
find_articulation_and_bridges_dfs(dfs_root);
articulations[dfs_root] = root_children_count > 1;
}