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++ program 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.



Improved By : nidhi_biet