Language: C++

#include <iostream>
#include <vector>
#include <algorithm>

#define show(x) cerr << #x << " = " << x << endl

using namespace std;
using ll = long long;

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
    os << "sz:" << v.size() << "\n[";
    for (const auto& p : v) {
        os << p << ",";
    }
    os << "]\n";
    return os;
}
template <typename S, typename T>
ostream& operator<<(ostream& os, const pair<S, T>& p)
{
    os << "(" << p.first << "," << p.second
       << ")";
    return os;
}


struct Graph {
    Graph(const int v) : V{v}
    {
        edge.resize(v);
        rev_edge.resize(v);
    }
    void addEdge(const int from, const int to)
    {
        edge[from].push_back(to);
        rev_edge[to].push_back(from);
    }
    vector<vector<int>> edge;
    vector<vector<int>> rev_edge;
    const int V;
};

class BiconnectedComponent
{
public:
    BiconnectedComponent(const Graph& g_) : num{0}, comp_num{0}, size{g_.V}, bridge(0), ord(size, -1), low(size, 0), comp(size, -1)
    {
        for (int i = 0; i < size; i++) {
            if (ord[i] == -1) {
                bridge_dfs(g_, i);
            }
        }
        for (int i = 0; i < size; i++) {
            if (comp[i] >= 0) {
                continue;
            }
            comp_dfs(g_, i, comp_num);
            comp_num++;
        }
    }

    Graph toTree() const
    {
        Graph tree(comp_num);
        for (const auto& p : bridge) {
            tree.addEdge(comp[p.first], comp[p.second]);
            tree.addEdge(comp[p.second], comp[p.first]);
        }
        return tree;
    }
    const vector<pair<int, int>>& getEdge() const
    {
        return bridge;
    }
    const vector<int>& getComp() const
    {
        return comp;
    }

    const vector<pair<int, int>> getBridge() const
    {
        return bridge;
    }
    bool isBridge(const int i, const int j) const
    {
        return (ord[i] < ord[j]) ? (ord[i] < low[j]) : (ord[j] < low[i]);
    }

private:
    void bridge_dfs(const Graph& g_, const int s, const int par = -1)
    {
        ord[s] = num;
        low[s] = num;
        num++;
        for (const int to : g_.edge[s]) {
            if (to == par) {
                continue;
            }
            if (ord[to] >= 0) {
                low[s] = min(low[s], ord[to]);
            } else {
                bridge_dfs(g_, to, s);
                low[s] = min(low[s], low[to]);
                if (isBridge(s, to)) {
                    bridge.push_back(make_pair(s, to));
                }
            }
        }
    }

    void comp_dfs(const Graph& g_, const int s, const int c)
    {
        comp[s] = c;
        for (const int to : g_.edge[s]) {
            if ((comp[to] == -1) and (not isBridge(s, to))) {
                comp_dfs(g_, to, c);
            }
        }
    }

    int num;
    int comp_num;
    const int size;
    vector<pair<int, int>> bridge;
    vector<int> ord;
    vector<int> low;
    vector<int> comp;
};

int main()
{
    int V, E;
    cin >> V >> E;
    Graph g(V);
    using P = pair<int, int>;
    vector<P> edge;
    for (int i = 0; i < E; i++) {
        int s, t;
        cin >> s >> t;
        if (s > t) {
            swap(s, t);
        }
        g.addEdge(s, t);
        g.addEdge(t, s);
        edge.push_back(make_pair(s, t));
    }

    BiconnectedComponent bic(g);
    for (int i = 0; i < E; i++) {
        const int u = edge[i].first;
        const int v = edge[i].second;
    }
    const vector<P> b = bic.getBridge();
    sort(b.begin(), b.end());
    for (const auto& p : b) {
        cout << p.first << " " << p.second << endl;
    }

    return 0;
}

Compiler output:
In file included from /usr/include/c++/14/algorithm:61,
                 from a.cc:3:
/usr/include/c++/14/bits/stl_algo.h: In instantiation of 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]':
/usr/include/c++/14/bits/stl_algo.h:1817:25:   required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
 1817 |           std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
      |           ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:1908:31:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
 1908 |           std::__final_insertion_sort(__first, __last, __comp);
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:4772:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >]'
 4772 |       std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      |       ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:156:9:   required from here
  156 |     sort(b.begin(), b.end());
      |     ~~~~^~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:1782:24: error: passing 'const std::pair<int, int>' as 'this' argument discards qualifiers [-fpermissive]
 1782 |               *__first = _GLIBCXX_MOVE(__val);
      |                        ^
In file included from /usr/include/c++/14/bits/stl_algobase.h:64,
                 from /usr/include/c++/14/string:51,
                 from /usr/include/c++/14/bits/locale_classes.h:40,
                 from /usr/include/c++/14/bits/ios_base.h:41,
                 from /usr/include/c++/14/ios:44,
                 from /usr/include/c++/14/ostream:40,
                 from /usr/include/c++/14/iostream:41,
                 from a.cc:1:
/usr/include/c++/14/bits/stl_pair.h:931:7: note:   in call to 'std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::__conditional_t<((bool)std::__and_<std::is_move_assignable<_Tp>, std::is_move_assignable<_T2> >::value), std::pair<_T1, _T2>&&, std::__nonesuch&&>) [with _T1 = int; _T2 = int; std::__conditional_t<((bool)std::__and_<std::is_move_assignable<_Tp>, std::is_move_assignable<_T2> >::value), std::pair<_T1, _T2>&&, std::__nonesuch&&> = std::pair<int, int>&&]'
  931 |       operator=(__conditional_t<__and_<is_move_assignable<_T1>,
      |       ^~~~~~~~
In file included from /usr/include/c++/14/bits/stl_algo.h:61:
/usr/include/c++/14/bits/stl_heap.h: In instantiation of 'void std::__pop_heap(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]':
/usr/include/c++/14/bits/stl_algo.h:1596:19:   required from 'void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
 1596 |           std::__pop_heap(__first, __middle, __i, __comp);
      |           ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:1868:25:   required from 'void std::__partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
 1868 |       std::__heap_select(__first, __middle, __last, __comp);
      |       ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:1884:27:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
 1884 |               std::__partial_sort(__first, __last, __last, __comp);
      |               ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:1905:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
 1905 |           std::__introsort_loop(__first, __last,
      |           ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
 1906 |                                 std::__lg(__last - __first) * 2,
      |                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1907 |                                 __comp);
      |                                 ~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:4772:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >]'
 4772 |       std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
      |       ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:156:9:   required from here
  156 |     sort(b.begin(), b.end());
      |     ~~~~^~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_heap.h:263:17: error: no match for 'operator=' (operand types are 'const std::pair<int, int>' and 'std::remove_reference<const std::pair<int, int>&>::type' {aka 'const std::pair<int, int>'})
  263 |       *__result = _GLIBCXX_MOVE(*__first);
      |                 ^
/usr/include/c++/14/bits/stl_pair.h:946:9: note: candidate: 'typename std::enable_if<std::__and_<std::is_assignable<_T1&, const _U1&>, std::is_assignable<_T2&, const _U2&> >::value, std::pair<_T1, _T2>&>::type std::pair<_T1, _T2>::operator=(const std::pair<_U1, _U2>&) [with _U1 = int; _U2 = int; _T1 = int; _T2 = int; typename std::enable_if<std::__and_<std::is_assignable<_T1&, const _U1&>, std::is_assignable<_T2&, const _U2&> >::value, std::pair<_T1, _T2>&>::type = std::pair<int, int>&]' (near match)
  946 |         operator=(const pair<_U1, _U2>& __p)
      |         ^~~~~~~~
/usr/include/c++/14/bits/stl_pair.h:946:9: note:   passing 'const std::pair<int, int>*' as 'this' argument discards qualifiers
/usr/include/c++/14/bits/stl_pair.h:921:7: note: candidate: 'std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::__conditional_t<((bool)std::__and_<std::is_copy_assignable<_T1>, std::is_copy_assignable<_T2> >::value), const std::pair<_T1, _T2>&, const std::__nonesuch&>) [with _T1 = int; _T2 = int; std::__conditional_t<((bool)std::__and_<std::is_copy_assignable<_T1>, std::is_copy_assignable<_T2> >::value), const std::pair<_T1, _T2>&, const std::__nonesuch&> = const std::pair<int, int>&]' (near match)
  921 |       operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
      |       ^~~~~~~~
/usr/include/c++/14/bits/stl_pair.h:921:7: note:   passing 'const std::pair<int, int>*' as 'this' argument discards qualifiers
/usr/include/c++/14/bits/stl_pair.h:931:7: note: candidate: 'std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::__conditional_t<((bool)std::__and_<std::is_move_assignable<_Tp>, std::is_move_assignable<_T2> >::value), std::pair<_T1, _T2>&&, std::__nonesuch&&>) [with _T1 = int; _T2 = int; std::__conditional_t<((bool)std::__and_<std::is_move_assignable<_Tp>, std::is_move_assignable<_T2> >::value), std::pair<_T1, _T2>&&, std::__nonesuch&&> = std::pair<int, int>&&]' (near match)
  931 |       operator=(__conditional_t<__and_<is_move_assignable<_T1>,
      |       ^~~~~~~~
/usr/include/c++/14/bits/stl_pair.h:931:7: note:   conversion of argument 1 would be ill-formed:
/usr/include/c++/14/bits/stl_pair.h:931:7: error: binding reference of type 'std::__conditional_t<true, std::pair<int, int>&&, std::__nonesuch&&>' {aka 'std::pair<int, int>&&'} to 'std::remove_reference<const std::pair<int, int>&>::type' {aka 'const std::pair<int, int>'} discards qualifiers
/usr/include/c++/14/bits/stl_pair.h:957:9: note: candidate: 'template<class _U1, class _U2> typename std::enable_if<std::__and_<std::is_assignable<_T1&, _U1&&>, std::is_assignable<_T2&, _U2&&> >::value, std::pair<_T1, _T2>&>::type std::pair<_T1, _T2>::operator=(std::pair<_U1, _U2>&&) [with _U2 = _U1; _T1 = int; _T2 = int]'
  957 |         operator=(pair<_U1, _U2>&& __p)
      |         ^~~~~~~~
/usr/include/c++/14/bits/stl_pair.h:957:9: note:   template argument deduction/substitution failed:
/usr/include/c++/14/bits/stl_heap.h:263:17: note:   types 'std::pair<_T1, _T2>' and 'std::remove_reference<const std::pair<int, int>&>::type' {aka 'const std::pair<int, int>'} have incompatible cv-qualifiers
  263 |       *__result = _GLIBCXX_MOVE(*__first);
      |                 ^
/usr/include/c++/14/bits/stl_algobase.h: In instantiation of 'void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _ForwardIterator2 = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >]':
/usr/include/c++/14/bits/stl_algo.h:91:20:   required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator, _Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<const pair<int, int>*, vector<pair<int, int> > >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
   91 |             std::iter_swap(__result, __b);
      |             ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algo.h:1855:34:   required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIte