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 C (judge verdict: Time Limit Exceeded)

#include<stdio.h>
#include<stdlib.h>

struct node {
  int id;
  struct node *next;
};
struct pair {
  int x;
  int y;
};
struct node **list;
struct pair *art;
int *seq, counter,sp;

void Insert(int, int);
int Biconnected(int, int);
void qsort1(int, int);
int main(void)
{
  int i, j, v, e, s, t;
  scanf("%d %d", &v, &e);
  list = (struct node**)malloc(sizeof(struct node*) * v);
  art = (struct pair*)malloc(sizeof(struct pair) * e);
  seq = (int*)calloc(v, sizeof(int));
  for (i = 0; i < v; i++) {
    list[i] = NULL;

  }
  for (i = 0; i < e; i++) {
    scanf("%d %d", &s, &t);
    Insert(s,t);
  }
  Biconnected(0, -1);
  qsort1(0, sp - 1);
  for (i = sp-1; i >= 0; i--) printf("%d %d\n", art[i].x, art[i].y);
  for (i = 0; i < v; i++) {
    free(list[i]);
  }
  free(list);
  free(seq);
  free(art);
}
void Insert(int a, int b)
{
  struct node *p = (struct node*)malloc(sizeof(struct node));
  p->id = b;
  p->next = list[a];
  list[a] = p;
  p = (struct node*)malloc(sizeof(struct node));
  p->id = a;
  p->next = list[b];
  list[b] = p;
}
int Biconnected(int point, int pre)
{
  int min;
  struct node *n;
  counter++;
  seq[point] = counter;
  min = counter;
  for(n = list[point]; n != NULL; n = n->next) {
    if (!seq[n->id]) {
      int m;
      m = Biconnected(n->id, point);
      if (m < min) min = m;
      if (m > seq[point]) {
        if (point < n->id) {
          art[sp].x = point;
          art[sp].y = n->id;
        } else {
          art[sp].x = n->id;
          art[sp].y = point;
        }
        sp++;
      }
    } else if (n->id != pre) {
      if (seq[n->id] < min) {
        min = seq[n->id];
      }
    }
  }
  return min;
}
void qsort1(int left, int right) {
  struct pair pivot = art[(left + right) / 2];
  int i = left, j = right;
  if (left >= right) return;
  do{
    while (1) {
      if (art[i].x < pivot.x || (art[i].x == pivot.x && art[i].y < pivot.y)) break;
      i++;
    }
    while (1) {
      if (art[j].x > pivot.x || (art[j].x == pivot.x && art[j].y > pivot.y)) break;
      j--;
    }
    if (i <= j) {
      struct pair temp = art[i];
      art[i] = art[j];
      art[j] = temp;
      i++;
      j--;
    }
  }while(i <= j);
  qsort1(left, j);
  qsort1(i, right);
}