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



Sample input:
4 4
0 1
0 2
1 2
2 3


Sample output:
2

Submission status: Runtime Error

Solution code:
from sys import stdin
readline = stdin.readline

v, e = map(int, readline().split())
from collections import defaultdict
g = defaultdict(list)

for _ in range(e):
    s, t = map(int, readline().split())
    g[s].append(t)
    g[t].append(s)
    
visited = set()
lowest = [None] * v
parent = [None] * v
prenum = [None] * v
child = defaultdict(list)
root = 0

# dfs??§tree?????????
stack = [(root, None)]
while stack:
    u, prev = stack.pop()
    if u not in visited:
        parent[u] = prev
        if prev is not None:
            child[prev].append(u)
    visited |= {u}
    prenum[u] = lowest[u] = len(visited)
    
    stack.extend([(v, u) for v in g[u] if v not in visited])
            
leaf = [i for i in range(v) if not child[i]]
for li in leaf:
    while li is not None:
        candidate = [prenum[li]] + [prenum[i] for i in g[li] if i != parent[li]] + [lowest[i] for i in child[i]]
        lowest[li] = min(candidate)
        li = parent[li]

if 2 <= len(child[root]):
    print(root)
for i in range(1, v):
    if child[i] and any(prenum[i] <= lowest[j] for j in child[i]):
        print(i)

Submission status: Runtime Error

Solution code:
__author__ = 'zhewang711'

class Graph:
    def __init__(self):
        self.vertices = 0
        self.outgoing = {}
        self.root_cnt = 0
        # self.incoming = {}
        self.result = []

    def insert_vertice(self):
        self.vertices += 1
        self.outgoing[self.vertices - 1] = []
        # self.incoming[self.vertices - 1] = {}

    def insert_edge(self, s, d):
        if s >= self.vertices or d >= self.vertices:
            raise ValueError('edge cannot be inserted because vertex do not exist')
        else:
            self.outgoing[s].append(d)
            self.outgoing[d].append(s)

    def get_input(self):
        s = input()
        V, E = int(s.split()[0]), int(s.split()[1])
        self.discovery = [None for i in range(V)]
        self.clock = 0
        self.explored = [False for i in range(V)]
        self.father = [None for i in range(V)]
        self.backing = [None for i in range(V)]
        self.sub_have_backing = [None for i in range(V)]
        for i in range(V):
            self.insert_vertice()
        for i in range(E):
            s = input()
            self.insert_edge(int(s.split()[0]), int(s.split()[1]))



    def read_input(self, filename):
        f = open(filename, 'r')
        cnt = 0
        for line in f:
            if cnt == 0:
               cnt += 1
               V, E = int(line.split()[0]), int(line.split()[1])

               self.discovery = [None for i in range(V)]
               self.clock = 0
               self.explored = [False for i in range(V)]
               self.father = [None for i in range(V)]
               self.backing = [None for i in range(V)]
               self.sub_have_backing = [None for i in range(V)]

               for i in range(V):
                   self.insert_vertice()
            else:
                self.insert_edge(int(line.split()[0]), int(line.split()[1]))

    def DFS(self, root, father):
        self.explored[root] = True
        self.discovery[root] = self.clock
        self.backing[root] = self.clock
        self.clock += 1
        root_backing = float('inf')
        for ver in self.outgoing[root]:
            if not self.explored[ver]:
                ver_backing = self.DFS(ver, root)
                self.backing[root] = min(self.backing[root], self.backing[ver], ver_backing)
            else:
                if ver != father:
                    root_backing = min(self.backing[ver], root_backing)
        return root_backing

    def _critical_points(self, root):
        self.explored[root] = True
        self.discovery[root] = self.clock
        self.clock += 1
        is_leaf = True
        for ver in self.outgoing[root]:
            if not self.explored[ver]:
                if root == 0:
                    self.root_cnt += 1
                is_leaf = False
                self._critical_points(ver)
        if not is_leaf:
            if self.backing[root] >= self.discovery[root] and root != 0:
                self.result.append(root)
g = Graph()
#g.get_input()
g.read_input('1.txt')
g.DFS(0, None)
g.clock = 0
g.discovery = [None for i in range(g.vertices)]
g.explored = [False for i in range(g.vertices)]
g._critical_points(0)
if g.root_cnt >= 2:
    g.result.append(0)
l = sorted(g.result)
for i in l:
    print(i)

Submission status: Runtime Error

Solution code:
__author__ = 'zhewang711'

class Graph:
    def __init__(self):
        self.vertices = 0
        self.outgoing = {}
        self.root_cnt = 0
        # self.incoming = {}
        self.result = []

    def insert_vertice(self):
        self.vertices += 1
        self.outgoing[self.vertices - 1] = []
        # self.incoming[self.vertices - 1] = {}

    def insert_edge(self, s, d):
        if s >= self.vertices or d >= self.vertices:
            raise ValueError('edge cannot be inserted because vertex do not exist')
        else:
            self.outgoing[s].append(d)
            self.outgoing[d].append(s)

    def get_input(self):
        s = input()
        V, E = int(s.split()[0]), int(s.split()[1])
        self.discovery = [None for i in range(V)]
        self.clock = 0
        self.explored = [False for i in range(V)]
        self.father = [None for i in range(V)]
        self.backing = [None for i in range(V)]
        self.sub_have_backing = [None for i in range(V)]
        for i in range(V):
            self.insert_vertice()
        for i in range(E):
            s = input()
            self.insert_edge(int(s.split()[0]), int(s.split()[1]))



    def read_input(self, filename):
        f = open(filename, 'r')
        cnt = 0
        for line in f:
            if cnt == 0:
               cnt += 1
               V, E = int(line.split()[0]), int(line.split()[1])

               self.discovery = [None for i in range(V)]
               self.clock = 0
               self.explored = [False for i in range(V)]
               self.father = [None for i in range(V)]
               self.backing = [None for i in range(V)]
               self.sub_have_backing = [False for i in range(V)]
               self.is_leaf = [None for i in range(V)]

               for i in range(V):
                   self.insert_vertice()
            else:
                self.insert_edge(int(line.split()[0]), int(line.split()[1]))

    def DFS(self, root):
        self.explored[root] = True
        self.discovery[root] = self.clock
        self.backing[root] = self.clock
        self.clock += 1
        self.is_leaf[root] = True
        for ver in self.outgoing[root]:
            if not self.explored[ver]:
                self.is_leaf[root] = False
                self.DFS(ver)
                self.backing[root] = min(self.backing[root], self.backing[ver])
            else:
                self.backing[root] = min(self.backing[root], self.discovery[ver])

    def _critical_points(self, root):
        self.explored[root] = True
        self.discovery[root] = self.clock
        self.clock += 1
        for ver in self.outgoing[root]:
            if not self.explored[ver]:
                if root == 0:
                    self.root_cnt += 1
                if self.backing[ver] >= self.discovery[root] and root !=0 and not self.is_leaf[root]:
                    self.result.append(root)
                self._critical_points(ver)

g = Graph()
g.get_input()
#g.read_input('1.txt')
g.DFS(0)
g.clock = 0
g.discovery = [None for i in range(g.vertices)]
g.explored = [False for i in range(g.vertices)]
g._critical_points(0)
if g.root_cnt >= 2:
    g.result.append(0)
l = sorted(g.result)
for i in l:
    print(i)

Submission status: Runtime Error

Solution code:
__author__ = 'zhewang711'

class Graph:
    def __init__(self):
        self.vertices = 0
        self.outgoing = {}
        self.root_cnt = 0
        # self.incoming = {}
        self.result = set()

    def insert_vertice(self):
        self.vertices += 1
        self.outgoing[self.vertices - 1] = []
        # self.incoming[self.vertices - 1] = {}

    def insert_edge(self, s, d):
        if s >= self.vertices or d >= self.vertices:
            raise ValueError('edge cannot be inserted because vertex do not exist')
        else:
            self.outgoing[s].append(d)
            self.outgoing[d].append(s)

    def get_input(self):
        s = input()
        V, E = int(s.split()[0]), int(s.split()[1])
        self.discovery = [None for i in range(V)]
        self.clock = 0
        self.explored = [False for i in range(V)]
        self.father = [None for i in range(V)]
        self.backing = [None for i in range(V)]
        self.sub_have_backing = [None for i in range(V)]
        self.is_leaf = [None for i in range(V)]
        for i in range(V):
            self.insert_vertice()
        for i in range(E):
            s = input()
            self.insert_edge(int(s.split()[0]), int(s.split()[1]))



    def read_input(self, filename):
        f = open(filename, 'r')
        cnt = 0
        for line in f:
            if cnt == 0:
               cnt += 1
               V, E = int(line.split()[0]), int(line.split()[1])

               self.discovery = [None for i in range(V)]
               self.clock = 0
               self.explored = [False for i in range(V)]
               self.father = [None for i in range(V)]
               self.backing = [None for i in range(V)]
               self.sub_have_backing = [False for i in range(V)]
               self.is_leaf = [None for i in range(V)]

               for i in range(V):
                   self.insert_vertice()
            else:
                self.insert_edge(int(line.split()[0]), int(line.split()[1]))

    def DFS(self, root):
        self.explored[root] = True
        self.discovery[root] = self.clock
        self.backing[root] = self.clock
        self.clock += 1
        self.is_leaf[root] = True
        for ver in self.outgoing[root]:
            if not self.explored[ver]:
                self.is_leaf[root] = False
                self.DFS(ver)
                self.backing[root] = min(self.backing[root], self.backing[ver])
            else:
                self.backing[root] = min(self.backing[root], self.discovery[ver])

    def _critical_points(self, root):
        self.explored[root] = True
        self.discovery[root] = self.clock
        self.clock += 1
        for ver in self.outgoing[root]:
            if not self.explored[ver]:
                if root == 0:
                    self.root_cnt += 1
                if self.backing[ver] >= self.discovery[root] and root !=0 and not self.is_leaf[root]:
                    self.result.add(root)
                self._critical_points(ver)

g = Graph()
g.get_input()
#g.read_input('1.txt')
g.DFS(0)
g.clock = 0
g.discovery = [None for i in range(g.vertices)]
g.explored = [False for i in range(g.vertices)]
g._critical_points(0)
if g.root_cnt >= 2:
    g.result.add(0)
l = sorted(g.result)
for i in l:
    print(i)

Submission status: Runtime Error

Solution code:
n, m = map(int, input().split())

edges = [set() for _ in range(n)]

for _ in range(m):
    s, t = map(int, input().split())
    edges[s].add(t)
    edges[t].add(s)

prenum = [None] * n
parent = [None] * n
lowest = [None] * n
counter = 0


def dfs(cur, prev):
    global counter
    prenum[cur] = lowest[cur] = counter
    counter += 1
    for edge in edges[cur]:
        if prenum[edge] is not None:
            if edge != prev:
                lowest[cur] = min(lowest[cur], prenum[edge])
            continue
        parent[edge] = cur
        dfs(edge, cur)
        lowest[cur] = min(lowest[cur], lowest[edge])


dfs(0, 1)
ap = [False] * n
r = 0
for _ in filter(lambda x: x == 0, parent):
    r += 1
    if r > 1:
        ap[0] = True
        break

for i in range(1, n):
    p = parent[i]
    if p and prenum[p] <= lowest[i]:
        ap[p] = True

for i, e in enumerate(ap):
    if e: print(i)

Submission status: Runtime Error

Solution code:
def dfs(s,p):
    global V,color
    color[s]=1
    for i in V[s] :
        if color[i]==0 and i!=p:
            dfs(i,p)
    color[s]=2

def AP():
    global V,ap,n,color
    for i in xrange(n):
        color=[0]*n
        dfs(V[i][0],i)
        color[i]=2
        print color
        if color!=[2]*n:
            ap.append(i)

n,e=map(int,raw_input().split())
ap=[]
V=[[] for i in xrange(n)]
for i in xrange(e):
    s,t=map(int,raw_input().split())
    V[s].append(t)
    V[t].append(s)
AP()
for i in xrange(len(ap)):
    print(ap[i])

Submission status: Runtime Error

Solution code:
def dfs(s,p):
    global V,color
    color[s]=1
    for i in V[s] :
        if color[i]==0 and i!=p:
            dfs(i,p)
    color[s]=2

def AP():
    global V,ap,n,color
    for i in xrange(n):
        color=[0]*n
        dfs(V[i][0],i)
        color[i]=2
        if color!=[2]*n:
            ap.append(i)

n,e=map(int,raw_input().split())
ap=[]
V=[[] for i in xrange(n)]
for i in xrange(e):
    s,t=map(int,raw_input().split())
    V[s].append(t)
    V[t].append(s)
AP()
for i in xrange(len(ap)):
    print(ap[i])

Submission status: Runtime Error

Solution code:
def dfs(s,p,color):
    color[s]=1
    for i in V[s] :
        if color[i]==0 and i!=p:
            dfs(i,p,color)
    color[s]=2

def AP():
    for i in xrange(n):
        color=[0]*n
        dfs(V[i][0],i,color)
        color[i]=2
        if color!=[2]*n:
            ap.append(i)

n,e=map(int,raw_input().split())
ap=[]
V=[[] for i in xrange(n)]
for i in xrange(e):
    s,t=map(int,raw_input().split())
    V[s].append(t)
    V[t].append(s)
if e==0:
    if n>=3:
        for i in xrange(n):
            print(i)
    else:
        pass
else:
    AP()
for i in xrange(len(ap)):
    print(ap[i])

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(10*6)
def dfs(s,p,color):
    color[s]=1
    for i in V[s] :
        if color[i]==0 and i!=p:
            dfs(i,p,color)
    color[s]=2

def AP():
    for i in xrange(vn):
        if V[i]!=[]:
            color=[0]*vn
            dfs(V[i][0],i,color)
            color[i]=2
            if color!=[2]*vn:
                ap.append(i)
        else:
            ap.append(i)

vn,e=map(int,raw_input().split())
ap=[]
V=[[] for i in xrange(vn)]
for i in xrange(e):
    s,t=map(int,raw_input().split())
    V[s].append(t)
    V[t].append(s)
if e==0:
    if vn>=3:
        for i in xrange(vn):
            print(i)
    else:
        pass
else:
    AP()
    for i in xrange(len(ap)):
        print(ap[i])

Submission status: Runtime Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

from sys import stdin

UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_table(_v_info):
    for v_detail in _v_info:
        v_from, v_to = map(int, v_detail)
        init_adj_table[v_from].append(v_to)
        # undirected graph
        init_adj_table[v_to].append(v_from)
    return init_adj_table


def graph_dfs(current, prev):
    global timer
    pre_v[current] = lowest_v[current] = timer
    timer += 1

    color[current] = VISITED_IN_STACK

    for adj in adj_table[current]:
        if color[adj] is UNVISITED:
            parent_v[adj] = current

            graph_dfs(adj, current)

            lowest_v[current] = min(lowest_v[current], lowest_v[adj])
        elif adj is not prev:
            lowest_v[current] = min(lowest_v[current], pre_v[adj])

    return None


def art_points():
    graph_dfs(0, -1)

    v_count = 0
    for j in range(1, vertices):
        parent = parent_v[j]
        if parent == init_vertex_index:
            v_count += 1
        elif pre_v[parent] <= lowest_v[j]:
            ans.add(parent)

    if v_count > 1:
        ans.add(init_vertex_index)

    return ans


if __name__ == '__main__':
    _input = stdin.readlines()
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    pre_v, parent_v, lowest_v = ([-1] * vertices for _ in range(3))
    init_adj_table = tuple([] for _ in range(vertices))

    timer = 1
    # root
    init_vertex_index = 0

    ans = set()
    color = [UNVISITED] * vertices

    adj_table = generate_adj_table(v_info)

    res = art_points()
    if not res:
        pass
    else:
        # print(*sorted(art_points()), sep='\n')
        print(*sorted(res), sep='\n')

Submission status: Runtime Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

from sys import stdin

UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_table(_v_info):
    for v_detail in _v_info:
        v_from, v_to = map(int, v_detail)
        init_adj_table[v_from].append(v_to)
        # undirected graph
        init_adj_table[v_to].append(v_from)
    return init_adj_table


def graph_dfs(current, prev):
    global timer
    pre_v[current] = lowest_v[current] = timer
    timer += 1

    color[current] = VISITED_IN_STACK

    for adj in adj_table[current]:
        if color[adj] is UNVISITED:
            parent_v[adj] = current

            # recursive dfs
            graph_dfs(adj, current)

            lowest_v[current] = min(lowest_v[current], lowest_v[adj])
        elif adj is not prev:
            lowest_v[current] = min(lowest_v[current], pre_v[adj])

    return None


def art_points():
    graph_dfs(0, -1)

    v_count = 0
    for j in range(1, vertices):
        parent = parent_v[j]
        if parent == init_vertex_index:
            v_count += 1
        elif pre_v[parent] <= lowest_v[j]:
            ans.add(parent)

    if v_count > 1:
        ans.add(init_vertex_index)

    return ans


if __name__ == '__main__':
    # _input = stdin.readlines()
    _in = open('test.txt', 'rt')
    _input = _in.readlines()
    # raise SystemExit
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    pre_v, parent_v, lowest_v = ([0] * vertices for _ in range(3))
    init_adj_table = tuple([] for _ in range(vertices))

    timer = 1
    # root
    init_vertex_index = 0

    ans = set()
    color = [UNVISITED] * vertices

    adj_table = generate_adj_table(v_info)

    res = art_points()
    if not res:
        pass
    else:
        # print(*sorted(art_points()), sep='\n')
        print(*sorted(res), sep='\n')

Submission status: Runtime Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

from sys import stdin

UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_table(_v_info):
    for v_detail in _v_info:
        v_from, v_to = map(int, v_detail)
        init_adj_table[v_from].append(v_to)
        # undirected graph
        init_adj_table[v_to].append(v_from)
    return init_adj_table


def graph_dfs(current, prev):
    global timer
    pre_v[current] = lowest_v[current] = timer
    timer += 1

    color[current] = VISITED_IN_STACK

    for adj in adj_table[current]:
        if color[adj] is UNVISITED:
            parent_v[adj] = current

            # recursive dfs
            graph_dfs(adj, current)

            lowest_v[current] = min(lowest_v[current], lowest_v[adj])
        elif adj is not prev:
            lowest_v[current] = min(lowest_v[current], pre_v[adj])

    return None


def art_points():
    graph_dfs(0, -1)

    v_count = 0
    for j in range(1, vertices):
        parent = parent_v[j]
        if parent == init_vertex_index:
            v_count += 1
        elif pre_v[parent] <= lowest_v[j]:
            ans.add(parent)

    if v_count > 1:
        ans.add(init_vertex_index)

    return ans


if __name__ == '__main__':
    _input = stdin.readlines()
    # raise SystemExit
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    pre_v, parent_v, lowest_v = ([0] * vertices for _ in range(3))
    init_adj_table = tuple([] for _ in range(vertices))

    timer = 1
    # root
    init_vertex_index = 0

    ans = set()
    color = [UNVISITED] * vertices

    adj_table = generate_adj_table(v_info)

    res = art_points()
    if not res:
        pass
    else:
        # print(*sorted(art_points()), sep='\n')
        print(*sorted(res), sep='\n')

Submission status: Runtime Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

import sys

sys.setrecursionlimit(int(3e6))
UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_table(_v_info):
    for v_detail in _v_info:
        v_from, v_to = map(int, v_detail)
        init_adj_table[v_from].append(v_to)
        # undirected graph
        init_adj_table[v_to].append(v_from)
    return init_adj_table


def graph_dfs(current, prev):
    global timer
    pre_v[current] = lowest_v[current] = timer
    timer += 1

    color[current] = VISITED_IN_STACK

    for adj in adj_table[current]:
        if color[adj] is UNVISITED:
            parent_v[adj] = current

            # recursive dfs
            graph_dfs(adj, current)

            lowest_v[current] = min(lowest_v[current], lowest_v[adj])
        elif adj is not prev:
            lowest_v[current] = min(lowest_v[current], pre_v[adj])

    return None


def art_points():
    graph_dfs(dfs_root, -1)

    np = 0
    for v in range(1, vertices):
        parent = parent_v[v]
        if parent is dfs_root:
            np += 1
        elif pre_v[parent] <= lowest_v[v]:
            ans.add(parent)

    if np > 1:
        ans.add(dfs_root)

    return ans


if __name__ == '__main__':
    # _input = sys.stdin.readlines()
    with open('test.txt', 'rt') as _in:
        _input = _in.readlines()
    vertices, edges = map(int, _input[0].split())
    v_info = map(lambda x: x.split(), _input[1:])
    pre_v, parent_v, lowest_v = ([0] * vertices for _ in range(3))
    init_adj_table = tuple([] for _ in range(vertices))

    timer = 1
    # root
    dfs_root = 0

    ans = set()
    color = [UNVISITED] * vertices

    adj_table = generate_adj_table(v_info)

    res = art_points()
    if not res:
        pass
    else:
        # print(*sorted(art_points()), sep='\n')
        print(*sorted(res), sep='\n')

Submission status: Runtime Error

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

input:
5 4
0 1
1 2
2 3
3 4

output:
1
2
3
"""

import sys

sys.setrecursionlimit(int(1e4))


def dfs_Tarjan(current):
    global timer
    children = 0
    visited[current] = True
    disc[current] = low[current] = timer
    timer += 1

    for adj in adj_table[current]:
        if not visited[adj]:
            parent[adj] = current
            children += 1
            dfs_Tarjan(adj)
            low[current] = min(low[current], low[adj])
            # current vertex is the root of DFS tree
            if parent[current] == -1 and children > 1:
                art_set.add(current)
            elif parent[current] != -1 and low[adj] >= disc[current]:
                art_set.add(current)

        elif adj != parent[current]:
            low[current] = min(low[current], disc[adj])

    return None


def dfs_init():
    for v in range(v_num):
        if not visited[v]:
            dfs_Tarjan(v)

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    v_num, e_num = map(int, _input[0].split())
    edges = map(lambda x: x.split(), _input[1:])

    adj_table = tuple([] for _ in range(v_num))
    for edge in edges:
        source, target = map(int, edge)
        adj_table[source].append(target)
        adj_table[target].append(source)

    timer = 0
    art_set = set()
    parent = [-1] * v_num
    visited = [False] * v_num
    disc, low = ([float('inf')] * v_num for _ in range(2))

    dfs_init()
    if art_set:
        print(*sorted(art_set), sep='\n')

Submission status: Runtime Error

Solution code:
def dfs(v, tm):
    dts[v] = est[v] = tm
    child = 0

    for i in range(nv):
        if adj[v][i]:
            if parents[i] is None:
                child += 1
                parents[i] = v
                dfs(i, tm + 1)
                est[v] = min(est[v], est[i])

                if parents[v] is None and child > 1: aps[v] = True
                if parents[v] is not None and est[i] >= dts[v]: aps[v] = True

            elif parents[v] != i:
                est[v] = min(est[v], dts[i])

nv, ne = map(int, input().split(' '))
adj = [[False] * nv for _ in range(nv)]
est = [float('inf')] * nv
parents = [None] * nv
aps = [False] * nv
dts = [0] * nv

for _ in range(ne):
    s, t = map(int, input().split(' '))
    adj[s][t] = adj[t][s] = True

dfs(0, 0)
[print(i) if aps[i] else _ for i in range(nv)]

Submission status: Runtime Error

Solution code:
def dfs(v, tm):
    visited[v] = True
    dts[v] = est[v] = tm
    child = 0

    for i in range(nv):
        if adj[v][i]:
            if not visited[i]:
                child += 1
                parents[i] = v
                dfs(i, tm + 1)
                est[v] = min(est[v], est[i])

                if parents[v] is None and child > 1: aps[v] = True
                if parents[v] is not None and est[i] >= dts[v]: aps[v] = True

            elif parents[v] != i:
                est[v] = min(est[v], dts[i])

nv, ne = map(int, input().split(' '))
adj = [[False] * nv for _ in range(nv)]
est = [float('inf')] * nv
visited = [False] * nv
parents = [None] * nv
aps = [False] * nv
dts = [0] * nv

for _ in range(ne):
    s, t = map(int, input().split(' '))
    adj[s][t] = adj[t][s] = True

dfs(0, 0)

for i in range(nv):
    if aps[i]:
        print(i)

Submission status: Runtime Error

Solution code:
def dfs(G,s,p,prenum,T,parents):
    if len(G[s]) == 0: return p
    T[s] = set()
    prenum[s] = p
    for c in G[s]:
        if c in T: continue
        p = dfs(G,c,p+1,prenum,T,parents)
        T[s].add(c)
        T[c].add(s)
        parents[c] = s
    return p




def find(G):
    points = []
    lowest = {}
    prenum = {}
    parents = {0:None}
    T = {}
    dfs(G,0,1,prenum,T,parents)
    for s in G:
        lowest[s] = prenum[s]
        for t in G[s]:
            if not t in T[s]:
                if lowest[s] > prenum[t]:
                    lowest[s] = prenum[t]
    for s in T:
        for t in T[s]:
            if t==parents[s]: continue
            if lowest[s] > lowest[t]:
                lowest[s] = lowest[t]

    for s in T:
        p = parents[s]
        if p is None:
            if len(T[s])-1>1: points.append(s)
        else:
            if parents[p] is None: continue
            if prenum[p] < lowest[s]:
                points.append(p)

    return points

n,m = map(int,raw_input().split(' '))

G = {}
for i in range(n):
    G[i] = set()

for i in range(m):
    s,t = map(int,raw_input().split(' '))
    G[s].add(t)
    G[t].add(s)

points = find(G)
for p in sorted(points):
    print p

Submission status: Runtime Error

Solution code:
def dfs(G,s,p,prenum,T,parents):
    if len(G[s]) == 0: return p
    T[s] = set()
    prenum[s] = p
    for c in G[s]:
        if c in T: continue
        p = dfs(G,c,p+1,prenum,T,parents)
        T[s].add(c)
        T[c].add(s)
        parents[c] = s
    return p

def find(G):
    points = []
    lowest = {}
    prenum = {}
    parents = {0:None}
    T = {}
    dfs(G,0,1,prenum,T,parents)
    for s in G:
        lowest[s] = prenum[s]
        for t in G[s]:
            if not t in T[s]:
                if lowest[s] > prenum[t]:
                    lowest[s] = prenum[t]
    for s in T:
        for t in T[s]:
            if t==parents[s]: continue
            if lowest[s] > lowest[t]:
                lowest[s] = lowest[t]

    for s in T:
        p = parents[s]
        if p is None:
            if len(T[s])-1>1: points.append(s)
        else:
            if parents[p] is None: continue
            if prenum[p] < lowest[s]:
                points.append(p)

    return points

n,m = map(int,raw_input().split(' '))

G = {}
for i in range(n):
    G[i] = set()

for i in range(m):
    s,t = map(int,raw_input().split(' '))
    G[s].add(t)
    G[t].add(s)

points = find(G)
for p in sorted(points):
    print p

Submission status: Runtime Error

Solution code:
def dfs(G,s,p,prenum,T,parents,lowest):
    T[s] = set()
    prenum[s] = p
    lowest[s] = p
    if len(G[s]) == 0: return p
    for c in G[s]:
        if c in T:
            if lowest[s] > prenum[c]:
                lowest[s] = prenum[c]
        else:
            p = dfs(G,c,p+1,prenum,T,parents,lowest)
            T[s].add(c)
            T[c].add(s)
            parents[c] = s
            lowest[s] = min(lowest[s], lowest[c])
    return p




def find(G):
    points = set()
    lowest = {}
    prenum = {}
    parents = {0:None}
    T = {}
    dfs(G,0,1,prenum,T,parents,lowest)

    #print G
    #print T
    #print prenum
    #print lowest
    #print parents

    for s in T:
        p = parents[s]
        if p is None:
            if len(T[s])>1: points.add(s)
        else:
            if parents[p] is None: continue
            if prenum[p] <= lowest[s]:
                points.add(p)

    return points

n,m = map(int,raw_input().split(' '))

G = {}
for i in range(n):
    G[i] = set()

for i in range(m):
    s,t = map(int,raw_input().split(' '))
    G[s].add(t)
    G[t].add(s)

points = find(G)
for p in sorted(list(points)):
    print p

Submission status: Runtime Error

Solution code:
V,E = map(int, input().split())
#??£??\??????????????????
A = [[] for i in range(V)]
for i in range(E):
    s,t = map(int, input().split())
    A[s].append(t)
    A[t].append(s)
    
#?????????????¨???????
prenum = [None for i in range(V)]
#DFS???????????????????????????
parent = [None for i in range(V)]
#????????????????°??????????
lowest = [None for i in range(V)]
#?¨????????????°??????
visited = [False for i in range(V)]

def DFS(u = 0, prev = -1, timer = 0):
    prenum[u] = timer
    lowest[u] = timer
    timer += 1
    visited[u] = True
    
    for v in A[u]:
        if not visited[v]:
            parent[v] = u
            DFS(v, u, timer)
            lowest[u] = min(lowest[u], lowest[v])
        elif v != prev:
            lowest[u] = min(lowest[u], prenum[v])
DFS()

ans = set()
 
for u in range(1, V):
    p = parent[u]
    if prenum[p] <= lowest[u]:
        ans.add(p)
 
if parent.count(0) >= 2:
    ans.add(0)
else:
    ans.discard(0)
 
ans = list(ans)
ans.sort()
 
if ans:
    print(*ans, sep = '\n')