Problem:
Bridges

Find bridges of an undirected graph G(V, E).

A bridge (also known as a cut-edge) is an edge whose deletion increase the number of connected components.

Input

|V| |E|
s0 t0
s1 t1
:
s|E|-1 t|E|-1

, where |V| is the number of nodes and |E| is the number of edges in the graph. The graph nodes are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target nodes of i-th edge (undirected).

Output

A list of bridges of the graph ordered by name. For each bridge, names of its end-ponints, source and target (source < target), should be printed separated by a space. The sources should be printed ascending order, then the target should also be printed ascending order for the same source.

Constraints

1 ≤ |V| ≤ 100,000

0 ≤ |E| ≤ 100,000

The graph is connected

There are no parallel edges

There are no self-loops

Sample Input 1

4 4
0 1
0 2
1 2
2 3

Sample Output 1

2 3

Sample Input 2

5 4
0 1
1 2
2 3
3 4

Sample Output 2

0 1
1 2
2 3
3 4

Solution in Ruby (judge verdict: Accepted)


class Node
  attr_accessor :order, :parent, :child, :edges, :lowest, :visited, :isArticulation
  def initialize
    @order = nil
    @parent = -1
    @child = []
    @edges = []
    @lowest = nil
    @visited = false
    @isArticulation = false
  end
end

def dfs(root, g)
  t = 1
  stack = []
  g[root].order = g[root].lowest = t
  g[root].visited = true

  stack << root
  while stack.size > 0
    u = stack[-1]
    flag = true
    g[u].edges.each{|x|
      if g[x].visited == false
        t += 1
        g[x].order = g[x].lowest = t
        g[x].visited = true
        g[x].parent = u
        g[u].child << x
        flag = false
        g[u].lowest = [g[u].lowest, g[x].lowest].min
        stack << x
        break
      elsif x != g[u].parent
        g[u].lowest = [g[u].lowest, g[x].order].min
      end
    }
    if flag
      stack.pop
      g[u].child.each{|v|
        g[u].lowest = [g[u].lowest, g[v].lowest].min
        g[u].isArticulation = true if (u != root && g[u].order <= g[v].lowest)
        if g[u].order < g[v].lowest
          if u < v
            $bridge << [u, v]
          else
            $bridge << [v, u]
          end
        end
      }
    end
  end
  g[root].isArticulation = true if g[root].child.size > 1
end

$bridge = []

$t = 1
v, e = gets.split.map(&:to_i)
graph = Array.new(v){Node.new}
e.times{
  s, t = gets.split.map(&:to_i)
  graph[s].edges << t
  graph[t].edges << s
}

dfs(0, graph)

# v.times{|i|
#   puts "#{graph[i].order} #{graph[i].parent} #{graph[i].lowest} #{graph[i].child}"
# }

# v.times{|i|
#   if graph[i].isArticulation
#     puts i
#   end
# }

$bridge.sort.each{|a, b|
  puts "#{a} #{b}"
}