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 <vector>
#include <set>
#include <algorithm>
using namespace std;
const int MAX=10000;
vector<int>G[MAX];
int prenum[MAX],parent[MAX],lowest[MAX],flag[MAX];
int N,timer;
void dfs(int u){
    prenum[u]=lowest[u]=timer++;
    flag[u]=true;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(!flag[v]){
            parent[v]=u;
            dfs(v);
            lowest[u]=min(lowest[u],lowest[v]);
        }
        
    }
    //int minBackEdge=1000000;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(parent[u]!=v && parent[v]!=u)
            lowest[u]=min(lowest[u],prenum[v]);
    }
    
}
void art_points(){
    timer=1;
    dfs(0);
    set<int>s;
    int head=-1,count=0;
    for(int i=0;i<N;i++)
    {
        if(parent[i]==-1){
            head=i;
            continue;
        }
        int p=parent[i];
        if(p==head){
            count++;
            continue;
        }
        if(prenum[p]<=lowest[i])
            s.insert(p);
    }
    if(count>=2)s.insert(head);
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
        cout<<(*it)<<endl;
}
int main()
{
    int E,s,t;
    cin>>N>>E;
    for(int i=0;i<N;i++){
        prenum[i]=0;
        parent[i]=-1;
        flag[i]=false;
    }
    for(int i=0;i<E;i++){
        cin>>s>>t;
        G[s].push_back(t);
        G[t].push_back(s);
    }
    art_points();
    //dfs(0);
    return 0;
}