Problem:


  MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Depth First Search

  Depth-first search (DFS) follows the strategy to search ”deeper” in the graph whenever possible. In DFS, edges are recursively explored out of the most recently discovered vertex $v$ that still has unexplored edges leaving it. When all of $v$'s edges have been explored, the search ”backtracks” to explore edges leaving the vertex from which $v$ was discovered.

  This process continues until all the vertices that are reachable from the original source vertex have been discovered. If any undiscovered vertices remain, then one of them is selected as a new source and the search is repeated from that source.

  DFS timestamps each vertex as follows:

$d[v]$ records when $v$ is first discovered.

$f[v]$ records when the search finishes examining $v$’s adjacency list.

  Write a program which reads a directed graph $G = (V, E)$ and demonstrates DFS on the graph based on the following rules:

$G$ is given in an adjacency-list. Vertices are identified by IDs $1, 2,... n$ respectively.

IDs in the adjacency list are arranged in ascending order.

The program should report the discover time and the finish time for each vertex.

When there are several candidates to visit during DFS, the algorithm should select the vertex with the smallest ID.

The timestamp starts with 1.

Input

  In the first line, an integer $n$ denoting the number of vertices of $G$ is given. In the next $n$ lines, adjacency lists of $u$ are given in the following format:

$u$ $k$ $v_1$ $v_2$ ... $v_k$

$u$ is ID of the vertex and $k$ denotes its degree. $v_i$ are IDs of vertices adjacent to $u$.

Output

  For each vertex, print $id$, $d$ and $f$ separated by a space character in a line. $id$ is ID of the vertex, $d$ and $f$ is the discover time and the finish time respectively. Print in order of vertex IDs.

Constraints

$1 \leq n \leq 100$

Sample Input 1

4
1 1 2
2 1 4
3 0
4 1 3

Sample Output 1

1 1 8
2 2 7
3 4 5
4 3 6

Sample Input 2

6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0

Sample Output 2

1 1 12
2 2 11
3 3 8
4 9 10
5 4 7
6 5 6

  This is example for Sample Input 2 (discover/finish)

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.



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


Sample output:
1 1 8
2 2 7
3 4 5
4 3 6

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
v = []
tl = []
t = 1

def rec(node):
	global t, tl, v
	if tl[node-1][0] != -1:
		# print("ret", node, tl[node-1][0])
		return
	tl[node-1][0] = t
	t += 1
	# print("t: {}", t)
	adj = v[node-1][2:]
	# print("adj: ", adj)
	for i in adj:
		rec(v[i-1][0])
	tl[node-1][1] = t
	t += 1

def main():
	global v, tl
	n = int(input().strip())
	tl = [[-1, -1] for _ in range(n)]
	for i in range(n):
		l = list(map(int, input().strip().split()))
		v.append(l)
	for i in range(1, n+1):
		rec(i)
	for i in range(n):
		print("{} {} {}".format(i+1, tl[i][0], tl[i][1]))

if __name__ == '__main__':
	main()

Submission status: Accepted

Solution code:
n = int(input())

A = [[0] * n for _ in range(n)]

for _ in range(n):
    u, k, *v = list(map(int, input().split()))
    for j in v:
        A[u-1][j-1] = 1

# for row in A:
#     print(' '.join(list(map(str,row))))

t = 0
d = [None] * n
f = [None] * n

def dfs_recursive(u):
    global t
    t += 1
    d[u] = t
    for v in range(n):
        if A[u][v] == 1 and d[v] is None:
            dfs_recursive(v)
    t += 1
    f[u] = t

def dfs_stack(root):
    global t
    stack = []
    stack.append(root)
    while stack:

        # 一番最後の要素をなめる
        u = stack[-1]

        # 未訪問の場合は訪問済みにする
        if d[u] is None:
            t += 1
            d[u] = t

        # 次の訪問先を探す
        has_next_node = False
        for v in range(n):
            if A[u][v] == 1 and d[v] is None:
                stack.append(v)
                has_next_node = True
                break

        # 次の訪問先がなければ訪問終了
        if not has_next_node:
            t += 1
            # スタックから取り出す
            stack.pop()

            # 時刻を記録
            f[u] = t
            
for i in range(n):
    if d[i] is None:
        dfs_recursive(i)
        # dfs_stack(i)

for i in range(n):
    print(i+1, d[i], f[i])

Submission status: Accepted

Solution code:
WHITE = 0
GRAY = 1
BLACK = 2

n = int(input())

M = [[0] * n for i in range(n)]

d = [0] * (n)
f = [0] * (n)
color = [WHITE] * (n)


time = 0

def dfs_visit(u):
    global time
    time += 1
    color[u] = GRAY
    d[u] = time
    for v in range(n):
        if M[u][v] == 0:
            continue
        if color[v] == WHITE:
            dfs_visit(v)
    color[u] = BLACK
    time += 1
    f[u] = time

def dfs():
    for u in range(n):
        if color[u] == WHITE:
            dfs_visit(u)

    for u in range(n):
        print("{} {} {}".format(u+1, d[u], f[u]))


if __name__ == "__main__":
    for i in range(n):
        arr = list(map(int, input().split()))
        for v in (arr[2:]):
            M[arr[0]-1][v-1] = 1

    dfs()

Submission status: Accepted

Solution code:
INTERVAL = 1
WHITE = 0
GRAY = 1
BLACK = 2


def depth_first_search(u):
    global time

    time += INTERVAL
    d[u] += time
    color[u] = GRAY

    for v in range(n):
        if matrix[u][v] and color[v] == WHITE:
            depth_first_search(v)

    time += INTERVAL
    f[u] += time
    color[u] = BLACK

# INPUT
n = int(input())


time = 0
color = [WHITE] * n
d = [0] * n
f = [0] * n

matrix = [[0] * n for _ in range(n)]

for i in range(n):

    u, k, *V = map(int, input().split())

    for v in V:
        v -= 1
        matrix[i][v] = 1


# PROCESS
u_search = 0
while True:

    depth_first_search(u_search)

    if WHITE not in color:
        break
    else:
        u_search = color.index(WHITE)
        

# OUTPUT
for i in range(n):
    print(i + 1, d[i], f[i])

Submission status: Accepted

Solution code:
n = int(input())
G = []
for i in range(n):
    T = [0]*n
    G.append(T)
for i in range(n):
    L = list(map(int,input().split()))
    for j in range(2,len(L)):
        G[i][L[j]-1] += 1
time = 1
D = [-1]*n
F = [-1]*n
def dfs(src):
    global time
    D[src] = time
    time += 1
    for dst in range(n):
        if G[src][dst] == 1 and D[dst] == -1:
            dfs(dst)
    F[src] = time
    time += 1
for root in range(n):
    if D[root] == -1:
        dfs(root)
for i in range(n):
    print(i+1,D[i],F[i])

Submission status: Accepted

Solution code:
n = int(input())
al = [list(map(lambda s: int(s) - 1, input().split()))[2:] for _ in range(n)]
begin = [-1] * n
end = [-1] * n
not_visited = list(range(n))
t = 1
def dfs(u):
    global begin, end, t, not_visited
    begin[u] = t
    t += 1
    not_visited.remove(u)
    for v in al[u]:
        if begin[v] == -1:
            dfs(v)
    end[u] = t
    t += 1

while len(not_visited) > 0:
    dfs(not_visited[0])

for i in range(n):
    print('{} {} {}'.format(i + 1, begin[i], end[i]))

Submission status: Accepted

Solution code:
n=int(input())
ne=[[] for _ in range(n+1)]
for _ in range(n):
    u,k,*v=map(int,input().split())
    ne[u]=v

class dfs:
    def __init__(self, n, ne):
        self.n=n
        self.ne=ne
        self.d=[0]*(n+1)
        self.f=[0]*(n+1)
        self.t=0
    def search(self, a):
        self.t+=1
        self.d[a]=self.t
        for p in ne[a]:
            if self.d[p]==0:
                self.search(p)
        self.t+=1
        self.f[a]=self.t
DFS=dfs(n,ne)
for i in range(1,n+1):
    if DFS.d[i]==0:
        DFS.search(i)
    print(i,DFS.d[i],DFS.f[i])

Submission status: Accepted

Solution code:
n=int(input())

v=[[]]*n
for i in range(n):
    tmp=list(map(int,input().split()))
    tmp=[i-1 for i in tmp[2:]]
    v[i]=tmp

time=1
D=[-1 for _ in range(n)]
F=[-1 for _ in range(n)]

def dfs(src):
    global time
    D[src]=time
    time+=1
    for dst in v[src]:
        if D[dst]==-1:#未訪問
            dfs(dst)
    F[src]=time
    time+=1

for root in range(n):
    if D[root]==-1:
        dfs(root)

for i in range(n):
    print(i+1,D[i],F[i])

Submission status: Accepted

Solution code:
n = int(input())

adj = [ [] for _ in range (n) ]

for i in range(n):
    _, _, *adj[i] = list(map(int, input().split()))

d = [0] * n
f = [0] * n
flag = [0] * n
time = 0

def dfs(u):
    global time
    time += 1
    flag[u-1] = 1
    d[u-1] = time
    
    for v in adj[u-1]:
        if flag[v-1] == 0:
            dfs(v)

    time += 1
    f[u-1] = time

for i in range(n):
    if flag[i] == 0:
        dfs(i+1)

for i in range(n):
    print(i+1, d[i], f[i])

Submission status: Accepted

Solution code:
# vim: set fileencoding=utf-8:
import sys
from functools import lru_cache

n = int(sys.stdin.readline().rstrip())
graph = [[0] * (n+1) for _ in range(n+1)]
for i in range(1, n+1):
    tmp = [int(ele) for ele in sys.stdin.readline().rstrip().split()]
    for j in tmp[2:]:
        graph[i][j] = 1

d = [-1] * (n+1)
f = [-1] * (n+1)
yet = [ele for ele in range(1, n+1)]
ct = 0


def main():
    while yet:
        stack = [min(yet)]
        dfs(stack)

    for i, detected_at, finished_at in zip(range(1, n + 1), d, f):
        print(str(i) + " " + str(detected_at) + " " + str(finished_at))


def dfs(stack):
    global yet, ct, graph, d, f
    ct += 1
    d[stack[-1]-1] = ct
    yet.remove(stack[-1])

    for i, adjacency in enumerate(graph[stack[-1]]):
        if adjacency == 1 and i in yet:  # 隣接かつ未探索であれば、stackにpush
            stack.append(i)
            dfs(stack)
    else:
        ct += 1
        f[(stack[-1]-1)] = ct
        stack.pop()


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
import sys

time = 0
def dfs(u):
    global time
    flag_list[u] = 1
    time += 1
    d_list[u] = time
    for v in range(n):
        if m_list[u][v] == 1 and flag_list[v] == 0:
            dfs(v)
    flag_list[u] = 2
    time += 1
    f_list[u] = time


input = sys.stdin.readline
n = int(input())
m_list = [[0]*n for _ in range(n)]
for _ in range(n):
    input_list = list(map(int, input().split()))
    index = input_list[0] - 1
    if input_list[1] > 0:
        for a in input_list[2:]:
            m_list[index][a-1] = 1
    
d_list = [0]*n
f_list = [0]*n
flag_list = [0]*n # 0: 未到達, 1: 処理中, 2: 完了
for i in range(n):
    if flag_list[i] == 0:
        dfs(i)

for i in range(n):
    print(i+1, d_list[i], f_list[i])

Submission status: Accepted

Solution code:
n = int(input())
a = []
for i in range(n):
    a += [list(map(int, input().split()))[2:]]
cnt = 1
pre = [0]*n
aft = [0]*n
color = [0]*n
def dfs(s):
    global cnt
    pre[s-1] = cnt
    cnt += 1
    color[s-1] = 1
    for i in a[s-1]:
        if color[i-1] == 0:dfs(i)
    aft[s-1] = cnt
    cnt += 1

for i in range(n):
    if color[i] == 0:
        dfs(i+1)

for i in range(n):
    print(i+1, pre[i], aft[i])

Submission status: Accepted

Solution code:

n = int(input())
g_list = {}
for _ in range(n):
    n1, num, *cl = map(int, input().split())
    g_list[n1] = cl


# 深さ優先探索: クラス使って書く？
class Graph():
    def __init__(self, g_list):
        self.time = 0
        self.nodes = {}
        self.d = {}
        self.f = {}
        self.g_list = g_list

    def dfs(self, node):
        self.time += 1
        self.d[node] = self.time
        for node_ in self.g_list[node]:
            if node_ not in self.d:
                self.dfs(node_)
        self.time += 1
        self.f[node] = self.time


g = Graph(g_list)
for i in range(1, n+1):
    if i not in g.d:
        g.dfs(i)

for g, f in zip(sorted(g.d.items()), sorted(g.f.items())):
    print(g[0], g[1], f[1])

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
"""
Created on Sat Apr  6 11:36:14 2019

@author: Yamazaki Kenichi
"""

n = int(input())
A = [[]]
A = A + [list(map(int,input().split())) for i in range(n)]

def dfs(k):
    global counta
    for i in range(A[k][1]):
        if T[A[k][i+2]][0] == -1:
            T[A[k][i+2]][0] = 0
            T[A[k][i+2]][1] = counta
            counta += 1
            dfs(A[k][i+2])
    T[k][2] = counta
    T[k][0] = 1
    counta += 1

T = [[-1,-1,-1] for i in range(n+1)]
counta = 1
for i in range(1,n+1):
    if T[i][0] == -1:
        T[A[i][0]][0],T[A[i][0]][1] = 0, counta
        counta += 1
        dfs(i)

for i in range(1,n+1):
    print(" ".join(map(str,[i,T[i][1],T[i][2]])))

Submission status: Accepted

Solution code:
n = int(input())
g = [[0]*(n+1) for _ in range(n+1)]
for i in range(n):
    u, k, *v, = map(int, input().split())
    for vi in v:
        g[u][vi] = 1

d = [0]*(n+1)
f = [0]*(n+1)
t = 0


def dfs(u):
    global t
    if d[u] != 0:
        return
    t += 1
    d[u] = t
    for i, v in enumerate(g[u]):
        if v == 1:
            dfs(i)
    t += 1
    f[u] = t


for i in range(1, n+1):
    if d[i] == 0:
        dfs(i)
for i in range(1, n+1):
    print(f"{i} {d[i]} {f[i]}")

Submission status: Accepted

Solution code:
n = int(input())
adj = [[None for _ in range(n)] for _ in range(n)]
for i in range(n):
    l = list(map(int, input().split()))
    if l[1] == 0:
        continue 
    else:
        for j in range(2,len(l)):
            adj[l[0]-1][l[j]-1] = 1
color = ['white' for _ in range(n)]
d = [None for _ in range(n)]
f = [None for _ in range(n)]
time = 1

def dfs(node):
    global color
    global d 
    global f
    global time 
    S = [node]
    color[node -1] = 'grey'
    d[node -1] = time 
    while S:
        u = S[-1]
        v = 1
        while v <= n:
            if adj[u-1][v-1] == 1 and color[v-1] == 'white':
                break
            v += 1
        if v < n+1:
            color[v-1] = 'grey'
            time += 1
            d[v-1] = time 
            S.append(v)
        else:
            time += 1
            S.pop()
            color[u-1] = ['black']
            f[u-1] = time

for node in range(1, n+1):
    if color[node-1] == 'white':
        dfs(node)
        time += 1
for i in range(n):
    print(' '.join([str(i+1), str(d[i]), str(f[i])]))

Submission status: Accepted

Solution code:
from collections import defaultdict


n = int(input())
rel = defaultdict(set)

times = {}
for _ in range(n):
    rl = list(map(int, input().split()))
    p, ts = rl[0], rl[2:]
    rel[p] = sorted(ts, reverse=True)
    times[p] = {'first': 0, 'last': 0}

t = 0

for f in range(1, len(rel)+1):
    if times[f]['last']:
        continue
    stack = [f]
    while stack:
        u = stack[-1]
        if times[u]['first']:
            if not times[u]['last']:
                t += 1
                times[u]['last'] = t
            stack.pop()
            continue
        t += 1
        times[u]['first'] = t
        for v in rel[u]:
            if not times[v]['first']:
                stack.append(v)

for k in sorted(times):
    print(k, times[k]['first'], times[k]['last'])

Submission status: Accepted

Solution code:
# coding: utf-8

visited = [False]*101
discovery_time = [0]*101
finish_time = [0]*101
A = [[] for _ in range(101)]
time = 0

def dfs(n):
    global time
    if visited[n] == True:
        return
    time += 1
    discovery_time[n] = time
    visited[n] = True
    for i in A[n]:
        dfs(i)
    time += 1
    finish_time[n] = time

n = int(input().rstrip())
for i in range(n):
    line = [int(j) for j in input().rstrip().split()]
    A[i+1].extend(line[2:])

for i in range(n):
    dfs(i+1)
    
for i in range(n):
    print(str(i+1)+ " "+ str(discovery_time[i+1])+" "+str(finish_time[i+1]))

Submission status: Accepted

Solution code:
from sys import stdin
from collections import deque

def read_graph(n):
    A = [ [0]*(n+1) for _ in range(n+1) ]
    for _ in range(n):
        line = deque(stdin.readline().strip().split())
        i = line.popleft()
        line.popleft()
        for k in line:
            A[int(i)][int(k)] = 1
    return A

def dfs_ctrl(n, A):
    color = ["WHITE"] * (n+1)
    d = [0] * (n+1)
    f = [0] * (n+1)
    time = 0

    def dfs(u):
        nonlocal color
        nonlocal time
        if color[u] == "WHITE":
            color[u] = "GRAY"
            time += 1
            d[u] = time

            for v in range(1, n+1):
                if A[u][v] and color[v] == "WHITE":
                    dfs(v)
            color[u] = "BLACK"
            time += 1
            f[u] = time

    for i in range(1, n+1):
        if color[i] == "WHITE":
            dfs(i)

    for i in range(1, n+1):
        print(i, d[i], f[i])

n = int(input())
A = read_graph(n)
dfs_ctrl(n, A)

Submission status: Accepted

Solution code:
import sys
readline = sys.stdin.readline
write = sys.stdout.write

n = int(input())
G = [None for i in range(n+1)]
for i in range(n):
    node_id, k, *adj = map(int, readline().split())
    # adj.sort()
    G[node_id] = adj

begin = [0,]*(n+1)
end = [0,]*(n+1)
time = 1

def dfs(v):
    global time

    begin[v] = time

    adjlen = len(G[v])
    for i in range(adjlen):
        if begin[G[v][i]] != 0:
            continue
        time += 1
        dfs(G[v][i])
    time += 1
    end[v] = time

for i in range(1, n+1):
    if begin[i] == 0:
        if i != 1:
            time += 1 #新しく始点を選ぶのにもコストがかかる
        dfs(i)

for i in range(1, n+1):
    write(str(i) + " " + str(begin[i]) + " " + str(end[i]) + "\n")

Submission status: Accepted

Solution code:
def dfs(u):
    global time
    color[u] = 'Gray'
    time += 1
    d[u] = time
    for v in range(1, n+1):
        if data[u][v] == 0:
            continue
        if color[v] == 'White':
            dfs(v)
    color[u] = 'Black'
    time += 1
    f[u] = time


n = int(input())
A = [list(map(int, input().split()))for _ in range(n)]
data = [[0]*(n+1) for _ in range(n+1)]
color = ['White']*(n+1)
d = [None]*(n+1)
f = [None]*(n+1)
time = 0
for i in A:
    for j in i[2:]:
        data[i[0]][j] = 1

for u in range(1, n+1):
    if color[u] == 'White':
        dfs(u)
for i in range(1, n+1):
    print('{} {} {}'.format(i, d[i], f[i]))

Submission status: Accepted

Solution code:
N = int(input())
L = [[] for i in range(N+1)]
d = [0] * (N+1)
f = [0] * (N+1)

time = 0

def dfs(key):
    global time
    time += 1
    d[key] = time
    for i in range(len(L[key])):
        if d[L[key][i]] == 0:
            dfs(L[key][i])
    time += 1
    f[key] = time
        

for i in range(N):
    Q = list(map(int, input().split()))
    L[Q[0]].extend(Q[2:])

for i in range(1,N+1):
    if d[i] == 0:
        dfs(i)
        #print("done")

for i in range(1,N+1):
    print(i, d[i], f[i])

Submission status: Accepted

Solution code:
#-*- coding: utf-8 -*-
"""
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_11_B
"""
import itertools
import time
import logging

def input_from_txt(number=1):
    import requests
    url = "https://judgedat.u-aizu.ac.jp/testcases/ALDS1_11_B/%s/in" % number
    res = requests.get(url)
    input = res.text.split("\n")
    n = int(input[0])
    Ss = []
    for i in range(n):
        S = list(map(int, input[1+i].split()))
        Ss.append(S)
    return (n, Ss)

def input_array():
    n = int(input())
    Ss = []
    for i in range(n):
        S = list(map(int, input().split()))
        Ss.append(S)
    return (n, Ss)

def show_matrix(n, Ss):
    for i in range(n):
        vth = Ss[i][0]
        vd = Ss[i][1]
        adjs = Ss[i][2:]
        row = []
        for j in range(1, 1+n):
            if j in adjs: row.append(1)
            else: row.append(0)
        logging.info(" ".join(map(str, row)))

class Verticies:
    def __init__(self, id, value, degree, adjs:list):
        self.id = id
        self.value = value
        self.degree = degree
        self.d = 0 # timesamp
        self.f = 0 # timesamp
        self.adjs = adjs

    def visit(self, ts):
        logging.debug("miso0a: visiting id(%s)" % self.id)
        if not self.is_visited():
            self.d = ts
            logging.debug("visited id(%s) and ts stamped as %s" % (self.id, ts))
            logging.info("id:%s d:%s f:%s (preorder)" % (self.id, self.d, self.f))
            ts+=1
            logging.debug("miso1: ts incremented as %s" % ts)
        return ts

    def all_visit(self, ts):
        if self.adjs_all_visited() and not self.adjs_all_stamped():
            self.f = ts
            logging.info("id:%s d:%s f:%s (=================)" % (self.id, self.d, self.f))
            ts +=1
        return ts

    def is_visited(self):
        logging.debug ("miso9: id(%s) is_visited: %s(%s)" % (self.id, not self.d == 0, self.d))
        return (not self.d == 0)

    def adjs_all_visited(self):
        visited = [v.is_visited() for v in self.adjs]
        logging.debug("miso5: %s" % self.adjs)
        logging.debug("miso(visited): %s" % visited)
        completed = all(visited)
        logging.debug("miso(completed): %s" % completed)
        return completed

    def adjs_all_stamped(self):
        stamped = [v.f != 0 for v in self.adjs]
        logging.debug("--- miso5 ---: %s" % [x.f for x in self.adjs])
        logging.debug("miso(stamped): %s" % stamped)
        completed = all(stamped)
        logging.debug("miso(completed): %s" % completed)
        return completed

    def get_adjs_info(self):
        return zip([v.id for v in self.adjs], [v.f for v in self.adjs])




def instanciate_vertex(V:list):
    vertex = {}
    for v in V:
        id = int(v[0])
        degree = v[1]
        adjs = v[2:]
        vertices = Verticies(id, 0, degree, adjs)
        vertex[id] = vertices
    # switch from string to Instance
    for id, vertices in vertex.items():
        vertex[id].adjs = [ vertex[i] for i in vertex[id].adjs]
    # sort by young id ascendence
    return sorted(list(vertex.values()), key=lambda v: v.id)


ANSWER={}
def dfs(v: Verticies, ts, stack:list):
    logging.info("dfs(v.id:%s, ts:%s, stack:%s)" % (v.id, ts, [ x.id for x in stack]))
    if not v.is_visited():
        ts = v.visit(ts)

    if len(v.adjs) == 0 or (v.adjs_all_visited()):
        v.f = ts
        logging.warn("id:%s d:%s f:%s (=================)" % (v.id, v.d, v.f))
        ANSWER[v.id] = (v.id, v.d, v.f)
        ts +=1
        stack.pop()
    else:
        logging.info("adjs_info:%s= (========not yet =======)" % ([(a,b) for a, b in v.get_adjs_info()] ))

    for next_v in v.adjs:
        if not next_v.is_visited():
            stack.append(next_v)
            break
    # ts = v.visit(ts)
    # ts = v.all_visit(ts)

    return ts

def dfs_all(vertex:list):
    stack = []
    #stack.append(vertex[0])
    ts = 1
    fin = False
    while not fin:
        for i, v in enumerate(vertex):
            logging.info("i:%s == len(vertex)-1: %s" % ( i, len(vertex)-1))
            if not v.is_visited():
                stack.append(v)
                break
            if i == len(vertex)-1: fin = True
        while len(stack) > 0:
            v = stack[len(stack)-1]
            ts = dfs(v, ts, stack)
            logging.info("while stack non empty")
            #time.sleep(1)
        logging.info("while True")
        #time.sleep(1)


if __name__ == '__main__':
    logging.getLogger().setLevel(logging.ERROR)
    #mode = "test"
    mode = "prod"
    if mode == "test":
        (n, Ss) = input_from_txt(1)
        show_matrix(n, Ss)
        logging.getLogger().setLevel(logging.INFO)
        #logging.getLogger().setLevel(logging.DEBUG)
    else:
        (n, Ss) = input_array()

    vertex = instanciate_vertex(Ss)
    logging.debug(vertex)
    dfs_all(vertex)
    from collections import OrderedDict
    for id, d, f in OrderedDict(sorted(ANSWER.items())).values():
        print("%s %s %s" % (id, d, f))
    #dfs_all(vertex)

Submission status: Accepted

Solution code:
# http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_11_A&lang=jp
# Graph: python3
#  2018.12.05 yonezawa

import sys
input = sys.stdin.readline

class node:
    def __init__(self):
        n = self.n = int(input())
        self.cnt = 0
        self.start = [-1] * n
        self.end = [-1] * n
        self.pos = [1] * n
        self.nmap = [[0 for i in range(n)] for i in range(n)]

        for _ in range(n):
            l = list(map(int,input().split()))
            a = l[0] - 1
            for i in l[2:]:
                self.nmap[a][i-1] = 1
    def printMap(self):
        for i in self.nmap:
            print (*i)

    def printResult(self):
        for i in range(self.n):
            print(i+1,self.start[i],self.end[i])

    def dfs(self,u):
        self.cnt += 1
        self.start[u] = self.cnt
        self.pos[u] = 0
        for i in range(self.n):
            if self.nmap[u][i] == 1 and self.pos[i] == 1:    
                self.dfs(i)
        self.cnt += 1
        self.end[u] = self.cnt
                
def main():
    a = node()
    for i in range(a.n):
        if a.pos[i] == 1:
            a.dfs(i)
    a.printResult()

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:

n=int(input())
used=[False for i in range(n)]
d=[0 for i in range(n)]
f=[0 for i in range(n)]
mat=[]
for i in range(n):
    tmp=list(map(int,input().split()))
    mat.append(tmp[2:])

t=1
def dfs(now):
    global t
    if used[now]:
        return
    else:
        used[now]=True
    d[now]=t
    t+=1
    for i in range(len(mat[now])):
        dfs(mat[now][i]-1)
    f[now]=t
    t+=1

for i in range(n):
    if used[i]==False:
        dfs(i)
for i in range(n):
    print(i+1,d[i],f[i])

Submission status: Accepted

Solution code:
import sys

n = int(sys.stdin.readline())+1

m = [[0] * n for _ in range(n)]
discover_time = [-1] * n
finish_time = [0] * n
clock = -1

def walk(p):
    global clock
    clock += 1

    for i in range(n):
        if m[p][i]==0: continue
        if discover_time[i]<0:
            discover_time[i] = clock
            clock = walk(i)
            finish_time[i] = clock
            clock +=1

    return clock

m[0] = [1] * n
for i in range(1,n):
    cols = list(map(int, sys.stdin.readline().split()))
    for j in cols[2:]:
        m[i][j]=1

walk(0)

for i in range(1,n):
    print(i,discover_time[i],finish_time[i])

Submission status: Accepted

Solution code:
import sys

def push_vertex(frame, vtx, search_queue, outputs, vertices):
    #print("frame:{} push:{}".format(frame, vtx))
    outputs[vtx] = [frame, None]
    search_queue.append(vtx)
    [vertices[key].remove(vtx) for key in vertices.keys() if vtx in vertices[key]]

    return

def main():
    n = int(input())
    lines = sys.stdin.readlines()
    outputs = {}

    vertices = {}
    for i in range(n):
        idx, idx_n, *idx_vertices = lines[i].rstrip().split()
        vertices[int(idx)] = [int(x) for x in idx_vertices]

    vtx = 1
    frame = 1
    search_queue = []
    push_vertex(frame, vtx, search_queue, outputs, vertices)

    while len(vertices) != 0:
        frame += 1
        if len(search_queue) != 0:
            vtx = search_queue[-1]
        else:
            vtx = list(vertices.keys())[0]
            push_vertex(frame, vtx, search_queue, outputs, vertices)
            continue

        if len(vertices[vtx]) != 0:
            next_vtx = vertices[vtx][0]
            push_vertex(frame, next_vtx, search_queue, outputs, vertices)
        else:
            search_queue.pop()
            #print("frame:{},pop:{}".format(frame, vtx))
            del vertices[vtx]
            outputs[vtx][1] = frame

    #pprint.pprint(outputs)
    for key, value in sorted(outputs.items(), key=lambda x: x[0]):
        print("{} {} {}".format(key, value[0], value[1]))


main()

Submission status: Accepted

Solution code:
def dfs_init(color,n,dq):
	for i in range(n):
		color[i] = "White"

def next(u):
	for v in range(list_next[u],n):
		list_next[u] = v+1
		if list_m[u][v]:
			return v


def dfs_visit(u,color,dq,tt):
	tt = tt
	dq.append(u)
	color[u] = "Gray"
	list_d[u] = tt + 1
	tt += 1
	while dq:
		u = dq[-1]
		v = next(u)
		if v != None:
			if color[v] == "White":
				color[v] = "Gray"
				list_d[v] = tt + 1
				tt += 1
				dq.append(v)
		else:
			dq.pop()
			color[u] = "Black"
			list_f[u] = tt + 1
			tt += 1
	return tt

from collections import deque
n = int(input())
list_m = [[0]*n for i in range(n)]
list_next = [0] * n
list_color = [0] * n
list_d = [0]*n
list_f = [0]*n
dq = deque([])

for i in range(n):
	a,b,*args = map(int, input().split())
	for num in args:
		list_m[a-1][num-1] = 1
tt = 0
list_num = [i+1 for i in range(n)]
dfs_init(list_color,n,dq)
for u in range(n):
	if list_color[u] == "White":
		tt = dfs_visit(u,list_color,dq,tt)

for i in range(n):
	print(list_num[i], list_d[i] ,list_f[i])

Submission status: Accepted

Solution code:
import sys
readline = sys.stdin.readline
write = sys.stdout.write

N = int(readline())
G = [None]*(N+1)
for i in range(N):
    u, k, *vs = map(int, readline().split())
    G[u] = vs


begin = [-1]*(N+1)
end = [-1]*(N+1)
lb = iter(range(1, 2*N+1)).__next__
def dfs(v):
    begin[v] = lb()
    for w in G[v]:
        if begin[w] != -1:
            continue
        dfs(w)
    end[v] = lb()


for v in range(1, N+1):
    if begin[v] != -1:
        continue
    dfs(v)
write("\n".join("{} {} {}".format(*args) for args in zip(range(1, N+1), begin[1:], end[1:])))
write("\n")

Submission status: Accepted

Solution code:
class Node():
    def __init__(self, v):
        self.d = 0
        self.f = 0
        self.v = v

    def __repr__(self):
        return "Node({},{},{})".format(
            self.d, self.f, self.v)


def read_node():
    n = int(input())
    adj_list = [[] for _ in range(n + 1)]

    for _ in range(n):
        id, _, *v = [int(x) for x in input().split()]
        adj_list[id] = Node(v)

    return adj_list


def depth_first_search(adj_list):
    def dfs(id):
        nonlocal adj_list, timestamp

        adj_list[id].d = timestamp
        for adj_id in adj_list[id].v:
            if adj_list[adj_id].d == 0:
                timestamp += 1
                dfs(adj_id)
        timestamp += 1
        adj_list[id].f = timestamp

    timestamp = 1
    for id in range(1, len(adj_list)):
        if adj_list[id].d == 0:
            dfs(id)
            timestamp += 1


def print_result(adj_list):
    for id in range(1, len(adj_list)):
        print(id, adj_list[id].d, adj_list[id].f)


def main():
    adj_list = read_node()
    depth_first_search(adj_list)
    print_result(adj_list)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import heapq
from collections import deque
from enum import Enum
import sys
import math
from _heapq import heappush, heappop

BIG_NUM = 2000000000
MOD = 1000000007
EPS = 0.000000001

global current_time
global visited,go_time,back_time
global G


def dfs(node_id):
    global current_time #書かないとローカル変数扱いされる
    go_time[node_id] = current_time
    current_time += 1

    for next_node in G[node_id]:

        if visited[next_node] == True:
            continue
        visited[next_node] = True
        dfs(next_node)

    back_time[node_id] = current_time
    current_time += 1


V = int(input())

G = [[] for i in range(V)]

visited = [False]*V

go_time = [0]*V
back_time = [0]*V

for loop in range(V):
    node_id,num,*tmp_adj = list(map(int,input().split()))
    node_id -= 1
    for i in range(num):
        G[node_id].append(tmp_adj[i]-1)

current_time = 1;

for i in range(V):
    if visited[i] == True:
        continue
    visited[i] = True
    dfs(i)

for i in range(V):
    print("%d %d %d"%(i+1,go_time[i],back_time[i]))

Submission status: Accepted

Solution code:
def dfs(v, cnt):
  D[v] = cnt
  cnt += 1
  for c in edge[v]:
    if D[c] == -1:
      cnt = dfs(c, cnt)
  F[v] = cnt
  cnt += 1
  return cnt

N = int(input())
edge = [[] for _ in range(N)]
for _ in range(N):
  u, _, *v = map(lambda x:int(x)-1, input().split())
  edge[u] = sorted(v)
D, F = [-1] * N, [-1] * N
c = 1
for i in range(N):
  if D[i] == -1:
    c = dfs(i, c)
for i, (d, f) in enumerate(zip(D, F)):
  print(i + 1, d, f)