1. Edge-by-Edge Removal Connectivity Test
Intuition
Remove each edge one by one. Run BFS/DFS to count connected components. If components increase, the removed edge is a bridge.
Algorithm
- Count baseline connected components of original graph using BFS/DFS.
- For each edge (u, v) in the edge list:
- Remove (u, v) from the adjacency list.
- Run BFS/DFS to count new connected components.
- If new count > baseline count, record (u, v) as a bridge.
- Re-insert (u, v) back into the adjacency list.
- Return all recorded bridges.
#include <iostream>#include <vector>#include <algorithm> using namespace std; void dfs(int u, const vector<vector<int>>& adj, vector<bool>& visited, pair<int, int> skipEdge) { visited[u] = true; for (int v : adj[u]) { if ((u == skipEdge.first && v == skipEdge.second) || (u == skipEdge.second && v == skipEdge.first)) { continue; // Skip the candidate bridge edge } if (!visited[v]) { dfs(v, adj, visited, skipEdge); } }} int countComponents(int V, const vector<vector<int>>& adj, pair<int, int> skipEdge = {-1, -1}) { vector<bool> visited(V, false); int count = 0; for (int i = 0; i < V; ++i) { if (!visited[i]) { count++; dfs(i, adj, visited, skipEdge); } } return count;} vector<vector<int>> findBridgesBruteForce(int V, const vector<vector<int>>& edges) { vector<vector<int>> adj(V); for (const auto& e : edges) { adj[e[0]].push_back(e[1]); adj[e[1]].push_back(e[0]); } int baseComponents = countComponents(V, adj); vector<vector<int>> bridges; for (const auto& e : edges) { int u = e[0], v = e[1]; int newComponents = countComponents(V, adj, {u, v}); if (newComponents > baseComponents) { bridges.push_back({min(u, v), max(u, v)}); } } return bridges;} int main() { int V = 4; vector<vector<int>> edges = {{0, 1}, {1, 2}, {2, 0}, {1, 3}}; auto bridges = findBridgesBruteForce(V, edges); cout << "Bridges found: "; for (const auto& b : bridges) cout << "[" << b[0] << ", " << b[1] << "] "; cout << endl; return 0;}Time & Space Complexity
- Time complexity:
O(E * (V + E)) - Space complexity:
O(V + E)