Maximum number of bridges in a path of a given graph

Given an undirected graph, the task is to count the maximum number of Bridges between any two vertices of the given graph.

Examples:

Input: 
Graph
1 ------- 2 ------- 3 -------- 4
          |         |
          |         |
          5 ------- 6
Output: 2 
Explanation: 
There are 2 bridges, (1 - 2)
and (3 - 4), in the path from 1 to 4.

Input: 
Graph:
1 ------- 2 ------- 3 ------- 4
Output: 3 
Explanation: 
There are 3 bridges, (1 - 2), (2 - 3)
and (3 - 4) in the path from 1 to 4.

Approach:
Follow the steps below to solve the problem:

  • Find all the bridges in the graph and store them in a vector.
  • Removal of all the bridges reduces the graph to small components.
  • These small components do not have any bridges and they are weakly connected components which does not contain bridges in them.
  • Generate a tree consisting of the nodes connected by bridges, with the bridges as the edges.
  • Now, the maximum bridges in a path between any node is equal to the diameter of this tree.
  • Hence, find the diameter of this tree and print it as the answer.

Below is the implementation of the above approach

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ progrm to find the
// maximum number of bridges
// in any path of the given graph
  
#include <bits/stdc++.h>
using namespace std;
  
const int N = 1e5 + 5;
  
// Stores the nodes
// and their connections
vector<vector<int> > v(N);
  
// Store the tree with
// Bridges as the edges
vector<vector<int> > g(N);
  
// Stores the visited nodes
vector<bool> vis(N, 0);
  
// for finding bridges
vector<int> in(N), low(N);
  
// for Disjoint Set Union
vector<int> parent(N), rnk(N);
// for storing actaul bridges
vector<pair<int, int> > bridges;
  
// Stores the number of
// nodes and edges
int n, m;
// For finding bridges
int timer = 0;
  
int find_set(int a)
{
    // Function to find root of
    // the component in which
    // A lies
    if (parent[a] == a)
        return a;
  
    // Doing path compression
    return parent[a]
           = find_set(parent[a]);
}
  
void union_set(int a, int b)
{
    // Function to do union
    // between a and b
    int x = find_set(a), y = find_set(b);
  
    // If both are already in the
    // same component
    if (x == y)
        return;
  
    // If both have same rank,
    // then increase anyone's rank
    if (rnk[x] == rnk[y])
        rnk[x]++;
  
    if (rnk[y] > rnk[x])
        swap(x, y);
  
    parent[y] = x;
}
  
// Function to find bridges
void dfsBridges(int a, int par)
{
    vis[a] = 1;
    // Initialize in time and
    // low value
    in[a] = low[a] = timer++;
  
    for (int i v[a]) {
  
        if (i == par)
            continue;
  
        if (vis[i])
  
            // Update the low value
            // of the parent
            low[a] = min(low[a], in[i]);
        else {
  
            // Perform DFS on its child
            // updating low if the child
            // has connection with any
            // ancestor
            dfsBridges(i, a);
  
            low[a] = min(low[a], low[i]);
  
            if (in[a] < low[i])
  
                // Bridge found
                bridges.push_back(make_pair(i, a));
  
            // Otherwise
            else
  
                // Find union between parent
                // and child as they
                // are in same component
                union_set(i, a);
        }
    }
}
  
// Function to find diameter of the
// tree for storing max two depth child
int dfsDiameter(int a, int par, int& diameter)
{
    int x = 0, y = 0;
    for (int i g[a]) {
        if (i == par)
            continue;
  
        int mx = dfsDiameter(i, a, diameter);
  
        // Finding max two depth
        // from its children
        if (mx > x) {
            y = x;
            x = mx;
        }
        else if (mx > y)
            y = mx;
    }
  
    // Update diameter with the
    // sum of max two depths
    diameter = max(diameter, x + y);
  
    // Return the maximum depth
    return x + 1;
}
  
// Function to find maximum
// bridges bwtween
// any two nodes
int findMaxBridges()
{
  
    for (int i = 0; i <= n; i++) {
        parent[i] = i;
        rnk[i] = 1;
    }
  
    // DFS to find bridges
    dfsBridges(1, 0);
  
    // If no bridges are found
    if (bridges.empty())
        return 0;
  
    int head = -1;
  
    // Iterate over all bridges
    for (auto& i bridges) {
  
        // Find the endpoints
        int a = find_set(i.first);
        int b = find_set(i.second);
  
        // Generate the tree with
        // bridges as the edges
        g[a].push_back(b);
        g[b].push_back(a);
  
        // Update the head
        head = a;
    }
  
    int diameter = 0;
    dfsDiameter(head, 0, diameter);
  
    // Return the diameter
    return diameter;
}
  
// Driver Code
int main()
{
    /*
      
    Graph =>
  
        1 ---- 2 ---- 3 ---- 4
               |      | 
               5 ---- 6 
    */
  
    n = 6, m = 6;
  
    v[1].push_back(2);
    v[2].push_back(1);
    v[2].push_back(3);
    v[3].push_back(2);
    v[2].push_back(5);
    v[5].push_back(2);
    v[5].push_back(6);
    v[6].push_back(5);
    v[6].push_back(3);
    v[3].push_back(6);
    v[3].push_back(4);
    v[4].push_back(4);
  
    int ans = findMaxBridges();
  
    cout << ans << endl;
  
    return 0;
}

chevron_right


Output:

2

Time Complexity: O(N + M)
Auxiliary Space: O(N + M)

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.