Problem:
Articulation Points

Find articulation points of a given undirected graph G(V, E).

A vertex in an undirected graph is an articulation point (or cut vertex) iff removing it disconnects the graph.

Input

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

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

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

Output

A list of articulation points of the graph G ordered by name.

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

Sample Input 2

5 4
0 1
1 2
2 3
3 4

Sample Output 2

1
2
3

Solution in C++ (judge verdict: Accepted)

#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
using namespace std;
#define MAX 100000
vector<int>G[MAX];
int n;
bool visited[MAX];
int premium[MAX];
int parent[MAX];
int lowest[MAX];
int timer;
void dfs(int current,int prev){
  premium[current]=lowest[current]=timer;
  timer++;
  visited[current]=true;
  int next;
  for(int i=0;i<G[current].size();i++){
    next=G[current][i];
    if(!visited[next]){
      parent[next]=current;
      dfs(next,current);
      lowest[current]=min(lowest[current],lowest[next]);
    }else if(next!=prev){
      lowest[current]=min(lowest[current],premium[next]);
    }
  }
}
void art_points(){
  for(int i=0;i<n;i++) visited[i]=false;
  timer=1;
  dfs(0,-1);
  set<int>ap;
  int np=0;
  for(int i=1;i<n;i++){
    int p=parent[i];
    if(p==0) np++;
    else if(premium[p]<=lowest[i]) ap.insert(p);
  }
  if(np>1) ap.insert(0);
  for(set<int>::iterator it=ap.begin();it!=ap.end();it++) cout<<*it<<endl;
}
int main(){
  int m;
  scanf("%d%d",&n,&m);
  for(int i=0;i<m;i++){
    int s,t;
    scanf("%d%d",&s,&t);
    G[s].push_back(t);
    G[t].push_back(s);
  }
  art_points();
  return 0;
}