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:
def dfs(i):
    global t
    t += 1
    D[i] = t
    for e in es[i]:
        if D[e] == 0:
            dfs(e)
    t += 1
    F[i] = t


if __name__ == "__main__":
    N = int(input())
    es = [[] for _ in range(N+1)]
    for _ in range(N):
        ipts = [int(ipt) for ipt in input().split()]
        if ipts[1] > 0:
            es[ipts[0]] = ipts[2:]
    D = [0 for _ in range(N+1)]
    F = [0 for _ in range(N+1)]
    t = 0
    for i in range(1, N+1):
        if D[i] == 0:
            dfs(i)
    for i in range(1, N+1):
        print(i, D[i], F[i])

Submission status: Accepted

Solution code:
class Node:
    def __init__(self, data):
        self.data = data
        self.neighbors = list()
        self.find_time = 0
        self.end_time = 0

N = int(input())
work_id = 0
nodes = list()
nodes.append(Node(0))


for _ in range(N):
    tmp_list = list( map(int, input().split()) )
    node = Node(tmp_list[0])
    for i in range(tmp_list[1]):
        node.neighbors.append(tmp_list[i+2])
    nodes.append(node)
    nodes[0].neighbors.append(node.data)

# for node in nodes:
#     print(node.data, ":", node.neighbors)


def search(node):
    global work_id

    if node.find_time != 0:
        return
    
    if node.data != 0:
        work_id += 1
        node.find_time = work_id

    if len(node.neighbors) > 0:
        for neighbor in node.neighbors:
            search(nodes[neighbor])
    
    if node.data != 0:
        work_id += 1
        node.end_time = work_id

search(nodes[0])

for node in nodes:
    if node.data == 0: continue
    print(node.data, node.find_time, node.end_time)

Submission status: Accepted

Solution code:

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:
N = int(input())
inf = 10 ** 6
graph = [[] for i in range(N)]
visited = [0 for i in range(N)]
time = [[inf,inf] for i in range(N)]

for i in range(N):
  a = list(map(int,input().split()))
  a = list(map(lambda x: x - 1,a))
  k,n = a[0],a[1]
  if n >= 0:
    graph[k] = a[2:]

con = 0

def dfs(cur,par):
  #print("v",visited)
  global con
  visited[cur] = 1
  con += 1
  time[cur][0] = min(time[cur][0],con)
  #print("cur1,con1",cur,con)
  if (graph[cur] == [] or graph[cur] == [cur]):
    visited[cur] = 1
    time[cur][0] = min(con,time[cur][0])
    con += 1
    time[cur][1] = min(con,time[cur][1])
    #print("curif,conif",cur,con)
    return 
  else:
    for chi in graph[cur]:
      if visited[chi] == 0:
        dfs(chi,cur)
      if any(visited[i] == 0 for i in graph[cur]):
        continue
      else:
        con += 1
        time[cur][1] = min(con,time[cur][1])
        #print("cur2,con2",cur,con)
        return
dfs(0,-1)

if any([i == 0 for i in visited]):
  f = visited.index(0)
  dfs(f,f - 1)

for i,t in enumerate(time):
  print(i + 1 ,*t)

Submission status: Accepted

Solution code:
from collections import deque

seen=[]
first_order =[]
last_order = []

def dfs(g, v, first_ptr, last_ptr):
    first_ptr=first_ptr+1
    last_ptr=first_ptr
    
    first_order[v] = first_ptr
    seen[v]=True 
    for next_v in g[v]:
        if seen[next_v]:
            continue
        first_ptr, last_ptr=dfs(g, next_v, first_ptr, last_ptr)
    last_ptr=last_ptr+1
    first_ptr=last_ptr

    last_order[v] = last_ptr
    return first_ptr, last_ptr

icase=1
if icase==0:
    n,m=map(int,input().split())
    g = [deque([]) for _ in range(n + 1)]
    for i in range(m):
        a,b=map(int,input().split())
        g[a].append(b)
#        g[b].append(a) # 無向グラフ
elif icase==1:        
    n=int(input())
    u=[0]*n
    k=[0]*n
#    v=[[] for i in range(n)]
    g = [deque([]) for _ in range(n + 1)]
    for i in range(n):
        ai=list(map(int,input().split()))
        u[i]=ai[0]
        k[i]=ai[1]
        g[i]=deque(ai[2:])
        for j in range(len(g[i])):
            g[i][j]-=1    
elif icase==2:
    n=6
    u=[1,2,3,4,5,6]
    k=[2,2,1,1,1,0]
    g = [deque([]) for _ in range(n + 1)]

    g[0]=deque([1,2])
    g[1]=deque([2,3])
    g[2]=deque([4])
    g[3]=deque([5])
    g[4]=deque([5])
    g[5]=deque([])
    g[5]=deque()

seen=[False]*n
first_ptr=0
last_ptr=0
first_order =[-1]*n
last_order = [-1]*n

for v in range(n):
    if seen[v]:
        continue
    else:
        first_ptr, last_ptr=dfs(g,v,first_ptr, last_ptr)

for v in range(n):
    print(v+1,first_order[v],last_order[v])

Submission status: Accepted

Solution code:
#!/usr/bin/env python3

from pprint import pprint
from collections import deque, defaultdict
import itertools
import math
import sys

sys.setrecursionlimit(10 ** 6)
input = sys.stdin.buffer.readline
INF = float('inf')

n_nodes = int(input())
graph = [[] for _ in range(n_nodes)]

for _ in range(n_nodes):
    line = list(map(int, input().split()))
    u, k = line[0], line[1]
    if k > 0:
        for v in line[2:]:
            graph[u - 1].append(v - 1)
# pprint(graph)


def dfs(v):
    global time
    time += 1
    for v_adj in graph[v]:
        if d[v_adj] == -1:
            d[v_adj] = time
            dfs(v_adj)
    f[v] = time
    time += 1


d = [-1] * n_nodes
f = [-1] * n_nodes
time = 1

for v in range(n_nodes):
    if d[v] == -1:
        d[v] = time
        dfs(v)

# pprint(d)
# pprint(f)

for v in range(n_nodes):
    print(f"{v + 1} {d[v]} {f[v]}")

Submission status: Accepted

Solution code:
n = int(input())
g = [[] for _ in range(n+1)] #1-index
for i in range(n):
    u, k, *v = map(int, input().split())
    for j in v:
        g[u].append(j)

#-------------------------------------------
def dfs(v): #未訪問の点vから潜っていく
    global time
    seen[v] = 1 #訪問済にする
    time += 1
    d[v] = time
    if g[v]:
        for next_v in g[v]:
            if seen[next_v] == 1: continue
            dfs(next_v) #再帰
    
    time += 1
    f[v] = time
    
#-------------------------------------------
seen = [0]*(n+1) #1-index
seen[0] = 1
seen[1] = 1 
d = [0]*(n+1)
f = [0]*(n+1)
time = 0

dfs(1) #深堀り

for i in range(1,n+1): #孤立点対応
    if seen[i] == 0:
        dfs(i)

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

Submission status: Accepted

Solution code:
from collections import Counter
import sys

def input():
    return sys.stdin.readline().strip()

def dfs(v):
    start[v] = lb()
    for w in g[v]:
        if start[w] != None:
            continue
        dfs(w)
    end[v] = lb()

n = int(input())
g = [None] * (n+1)
start = [None] * (n+1)
end = [None] * (n+1)
lb = iter(range(1,2*n+1)).__next__
for _ in range(n):
    u,k,*vk = map(int,input().split())
    g[u] = vk
for v in range(1,n+1):
    if start[v] != None:
        continue
    dfs(v)

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

Submission status: Accepted

Solution code:
#Boost Force  / Backtracking
import sys
input = sys.stdin.readline
d = []
f = []
time = 0
#ทำการ search
def search(r):
    global d,f,time,s
    if d[r] == 0:
        time += 1
        d[r] = time
    else:
        return
    for x in s[r]:
        search(x)
    time += 1
    f[r] = time


n = int(input()) #รับค่าจำนวน node ทั้งหมด
s = [[] for i in range(n+1)]
for _ in range(n):
    d = list(map(int,input().split())) #รับข้อมูลทีละบรรทัด split เก็บเป็น int
    #ตน d[0] คือ node ตน 1 คือ ดีกรี ตนตั้งแต่ 2ไป คือ vertex
    s[d[0]] = d[2:]

d = [0 for _ in range(n+1)]
f = [0 for _ in range(n+1)]

for i in range(1,n+1):
    if d[i] == 0:
        search(i)

#แสดง node เวลาที่เจอ และ เวลา finish
for i in range(1,n+1):
    print (i,d[i],f[i])

Submission status: Accepted

Solution code:
import collections,sys
def I(): return int(sys.stdin.readline().rstrip())
def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))
n = I()
ukv = [LI() for _ in range(n)]
graph = {i:collections.deque() for i in range(1,n+1)} #1_indexed
for x in ukv:
    u,k,*v = x
    for y in v:
        graph[u].append(y)
seen = [0]*(n+1) #1_indexed
stack = []
time = 0
seentime = [0]*(n+1) #1_indexed
donetime = [0]*(n+1) #1_indexed
def dfs(j):
    global time
    seen[j] = 1
    stack.append(j)
    time += 1
    seentime[j] = time
    while stack:
        s = stack[-1]
        if not graph[s]:
            stack.pop()
            time += 1
            donetime[s] = time
            continue
        g_NO = graph[s].popleft()
        if seen[g_NO]:
            continue
        seen[g_NO] = 1
        stack.append(g_NO)
        time += 1
        seentime[g_NO] = time
for j in range(1,n+1):
    if seen[j]:
        continue
    dfs(j)
for k,a,b in zip(range(1,n+1),seentime[1:],donetime[1:]):
    print(k,a,b)

Submission status: Accepted

Solution code:
def dfs(v):
    global t, d, f, visited
    d[v] = t
    visited[v] = True
    t += 1
    for u in AL[v]:
        if not visited[u]:
            dfs(u)
    f[v] = t
    t += 1

# 入力
n = int(input())
AL = [[] for _ in range(n + 1)]
for v in range(1, n + 1):
    AL[v] = [int(x) for x in input().split()][2:]

# 計算
d = [0] * (n + 1)
f = [0] * (n + 1)
t = 1
visited = [False] * (n + 1)
for v in range(1, n + 1):
    if not visited[v]:
        dfs(v)

# 出力
for v in range(1, n + 1):
    print(v, d[v], f[v])

Submission status: Accepted

Solution code:
n = int(input())

graph = []
for _ in range(n):
    tmp = list(map(int, input().split()))
    if tmp[1] == 0:
        graph.append([])
    else:
        graph.append(tmp[2:])
#print(graph)

seen = [0]*n
to_do = []
in_list = [0]*n
out_list = [0]*n
count = 0

def dfs(v):
    #print(v)
    global count
    if seen[v] == 0:
        seen[v] = 1
        count += 1
        in_list[v] = count
        to_do = graph[v]
        #print(in_list)
        #print(to_do)
        if len(to_do) > 0:
            for i in to_do:
                dfs(i-1)
        count += 1
        out_list[v] = count
        #print(out_list)
while True:
    if 0 in seen:
        k = seen.index(0)
        dfs(k)
    else:
        break

for i in range(n):
    print("{} {} {}".format(i+1,in_list[i],out_list[i]))

Submission status: Accepted

Solution code:
def dfs(num, lst, d, f, cnt):
    if d[num] != 0:
        return cnt - 1
    d[num] = cnt
    for n in lst[num]:
        cnt += 1
        cnt = dfs(n - 1, lst, d, f ,cnt)
    cnt += 1
    f[num] = cnt
    return cnt


n = int(input())
d = [0 for i in range(n)]
f = [0 for i in range(n)]
lst = []
for _ in range(n):
    n = list(map(int, input().split()))
    lst.append(n[2:])

cnt = 1
while 0 in d:
    num = d.index(0)
    cnt = dfs(num, lst, d, f, cnt) + 1

for i, j in enumerate(zip(d, f)):
    print(i + 1, j[0], j[1])

Submission status: Accepted

Solution code:
from collections import deque
q = deque()

n = int(input())
C = [deque() for _ in range(n+1)]

for i in range(n):
    tmp = list(map(int,input().split()))
    for j in range(tmp[1]):
        C[tmp[0]].append(tmp[2+j])

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

def stack(i):
    global t
    if visited[i] == False:
        q.append(i)
    while q:
        #ノードの探索開始
        node = q[-1]
        if d[node] == 0:
            t += 1
            d[node] = t
        visited[node] = True
        for _ in range(len(C[node])):
            tmp = C[node].popleft()
            if visited[tmp] == False:
                next_node = tmp
                q.append(next_node)    #未探索の接続ノード
                break
        
        #未探索接続ノードがなければそのノードは探索終了
        else:
            t += 1
            f[q.pop()] = t

for i in range(1,n+1):
    stack(i)

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

Submission status: Accepted

Solution code:
cin = open(0).read().strip().split('\n')
n = int(cin[0])
g = [list(map(lambda x: int(x)-1, a.split(' ')[2:])) for a in cin[1:]]

first_order = [-1] * n
last_order = [-1] * n
ptr = 1

def dfs(g, seen, idx):
    global first_order, first_order, ptr

    first_order[idx] = ptr
    ptr += 1

    seen[idx] = True
    for i in g[idx]:
        # idxから行ける各頂点について
        if seen[i]: continue
        dfs(g, seen, i)

    last_order[idx] = ptr
    ptr += 1

seen = [False] * n
dfs(g, seen, 0)

# 孤立している頂点対策
for i in range(n):
    if not seen[i]:
        ans = dfs(g, seen, i)

# 出力
for idx, (f, l) in enumerate(zip(first_order, last_order)):
    print(idx+1, f, l)

Submission status: Accepted

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

#入力
n=int(readline())
m=n+1
u,k,v=[0]*m,[0]*m,[0]*m
for i in range(1,m):
    u[i],k[i],*v[i]=map(int,readline().split())

d=[0]*m
f=[0]*m
flags=[False]*m
t=0
def dfs(now):
    global t
    t+=1
    d[now]=t
    flags[now]=True
    for nex in v[now]:
        if flags[nex]==False:
            dfs(nex)
    t+=1
    f[now]=t
now=1
while True:
    dfs(now)
    for i in range(1,m):
        if flags[i]==False:
            now=i
            break
    else:
        break

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

Submission status: Accepted

Solution code:
N = int(input())
edge = [[0] for _ in range(N)]
for i in range(N):
    A = list(map(int, input().split()))
    for i,a in enumerate(A):
        A[i] -= 1
    edge[A[0]] = sorted(A[2:])
ans = [[0,0] for _ in range(N)]
import sys
sys.setrecursionlimit(10**8)

def dfs(v,now):
    if len(edge[v])>0:
        for u in edge[v]:
            if visited[u]==False:
                visited[u]=True
                now += 1
                ans[u][0] = now
                now = dfs(u,now)
    now += 1
    ans[v][1] = now
    return now

visited = [False]*N

now = 0
for i in range(N):
    if visited[i]==False:
        visited[i]=True
        now += 1
        ans[i][0] = now
        now = dfs(i,now)
for i in range(N):
    ans[i] = '{} {} {}'.format(i+1,ans[i][0],ans[i][1])
print(*ans,sep='\n')

Submission status: Accepted

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


N = int(input())
g = [0]*N
k = [0]*N
v = [[] for _ in range(N)]
for i in range(N):
    tmp = list(map(int, input().split()))
    g[i] = tmp[0]
    k[i] = tmp[1]
    if k[i] != 0:
        v[i] = sorted(tmp[2:])

D = [-1] * N
F = [-1] * N
cnt = 1
for i in range(N):
    if D[i] == -1:
        cnt = dfs(i, cnt)

for i, (d, f) in enumerate(zip(D, F)):
    print(i+1, d, f)

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
"""
Created on Thu May  7 23:19:34 2020

@author: Kanaru Sato
"""
def dfs(v):
    global t
    d[v] = t
    t += 1
    if conlist[v]:
        for connectedv in conlist[v]:
            if d[connectedv] == -1:
                dfs(connectedv)
    f[v] = t
    t += 1

n = int(input())
conlist = [[] for i in range(n)]
for i in range(n):
    _ = list(map(int,input().split()))
    [conlist[i].append(_[k]-1) for k in range(2,_[1]+2)]

d = [-1 for i in range(n)]
f = [-1 for i in range(n)]
t = 1

for i in range(n):
    if d[i] == -1:
        dfs(i)    

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

Submission status: Accepted

Solution code:
# -*- coding:utf-8 -*-

def solve():
    from collections import deque

    N = int(input())
    Us = [[] for _ in range(N)]

    for i in range(N):
        _in = list(map(int, input().split()))
        if len(_in) == 2:
            continue
        u, k, Vs = _in[0], _in[1], _in[2:]
        Vs.sort()
        for v in Vs:
            Us[u-1].append(v-1)
        Us[u-1] = deque(Us[u-1])

    find = [0 for _ in range(N)]  # 発見時刻
    terminated = [0 for _ in range(N)]  # 終了時刻
    tim = [0]  # 経過時間

    def dfs(now):
        while Us[now]:
            nxt = Us[now].popleft()

            if find[nxt] != 0:
                continue

            tim[0] += 1
            find[nxt] = tim[0]

            dfs(nxt)

        if terminated[now] == 0:
            tim[0] += 1
            terminated[now] = tim[0]

    for i in range(N):
        if find[i] == 0:
            tim[0] += 1
            find[i] = tim[0]
            dfs(i)

    for i in range(N):
        print(i+1, find[i], terminated[i])


if __name__ == "__main__":
    solve()

Submission status: Accepted

Solution code:
# http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_11_B&lang=ja
import sys
input = sys.stdin.readline

N = int(input())
G = [[a-1 for a in list(map(int, input().split()))[2:]] for _ in [0]*N]
visited = [0]*N
history = [[] for _ in [0]*N]

k = 0


def dfs(v=0, p=-1):
    global k
    visited[v] = 1
    k += 1
    history[v].append(k)

    for u in G[v]:
        if u == p or visited[u]:
            continue
        dfs(u, v)

    k += 1
    history[v].append(k)


for i in range(N):
    if not visited[i]:
        dfs(i)

for i, h in enumerate(history):
    print(i+1, *h)

Submission status: Accepted

Solution code:
n = int(input())
g = [[]for i in range(n)]
for i in range(n):
    v = list(map(int,input().split()))
    u = v[0]-1
    k = v[1]
    for j in range(k):
        g[u].append(v[j+2]-1)
time = 1
ans = []
d = [0]*n
f = [0] *n
visited = [0]*n

def dfs(now,last = -1):
    global time
    
    visited[now] = 1
    d[now] = time
    time += 1
    for next in g[now]:
        if visited[next]:continue
        dfs(next,now)
    f[now] = time
    time +=1
    
for i in range(n):
    if not visited[i]:dfs(i)
for i in range(n):
    print(i+1,d[i],f[i])

Submission status: Accepted

Solution code:
def dfs(vum,v,d,f,t):
    # print('first')
    # print(vum,v,d,f,t)
    if f[v] >= 0:
        return d,f,t
    t += 1
    d[v] = t
    for u in vum[v]:
        # print(v, d[v], f[v], u, d[u], f[u])
        if d[u] >= 0:
            # print('skip', str(v), str(u))
            continue
        d,f,t = dfs(vum,u,d,f,t)
    t += 1
    f[v] = t
    # print(v, d[v], f[v])
    # print('last')
    # print(vum,v,d,f,t)
    return d,f,t

def main():
    n = int(input())
    rows = []
    for i in range(n):
        rows.append([int(x) for x in input().split()])

    vum = {}
    for v,row in enumerate(rows):
        u,k = row[0],row[1]
        ul = []
        if k > 0:
            for j in row[2:]:
                ul.append(j-1)
        vum.update({v:ul})

    # print(vum)
    d = [-1]*len(vum)
    f = [-1]*len(vum)
    t = 0
    for v in vum:
        d,f,t = dfs(vum,v,d,f,t)
    for i,(j,k) in enumerate(zip(d,f)):
        print(i+1,j,k)

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
N = int(input())
edge = [[] for _ in range(N+1)]
d = [0] * (N+1)
f = [0] * (N+1)
for i in range(N):
    t = list(map(int, input().split()))
    for j in range(t[1]):
        edge[t[0]].append(t[j+2])

#print(1)
def dfs(v, t):
    if d[v] == 0:
        d[v] = t
        t += 1
    else:
        return t
    for nv in edge[v]:
        t = dfs(nv, t)
    if f[v] == 0:
        f[v] = t
        t += 1
    return t

t = 1
for i in range(1,1+N):
    if d[i] == 0:
        t = dfs(i, t)
for i in range(1,1+N):
    print(i, d[i], f[i])

Submission status: Accepted

Solution code:
# 深さ優先探索（行きがけ、帰りがけ）
import sys
input = sys.stdin.readline
from collections import deque

# グラフの作成(無向グラフでは#を消す)
N = int(input())
graph = [deque([]) for _ in range(N + 1)]
for _ in range(N):
    u, k, * v = [int(x) for x in input().split()] # uは頂点番号、kは隣接頂点の個数
    v.sort()
    for i in v:
        graph[u].append(i)
        # graph[i].append(u) # 無向グラフ

time = 0
arrive_time = [-1] * (N + 1) # 到着時刻
finish_time = [-1] * (N + 1) # 探索終了時刻

# 深さ優先探索
def dfs(v):
    global time
    time += 1
    stack = [v]
    arrive_time[v] = time
    while stack:
        v = stack[-1]
        if graph[v]:
            w = graph[v].popleft()
            if arrive_time[w] < 0:
                time += 1
                arrive_time[w] = time
                stack.append(w) 
        else:
            time += 1
            finish_time[v] = time
            stack.pop()          
    return [arrive_time, finish_time]

# 孤立している頂点対策
for i in range(N):
    if arrive_time[i + 1] < 0:
        ans = dfs(i + 1)

# 頂点番号、到着時刻、終了時刻
for j in range(N):
    temp = [j + 1, ans[0][j + 1], ans[1][j + 1]]
    print(* temp)

Submission status: Accepted

Solution code:
N = int(input())

G = [[0] * N for _ in range(N)]
time = 0
times = [{'s': 0, 'f': 0} for _ in range(N)]

for _ in range(N):
    u, n, *K = map(int, input().split())
    for k in K:
        G[u - 1][k - 1] = 1

def dfs(u):
    global time
    time += 1
    times[u]['s'] = time
    for i in range(N):
        if G[u][i] == 1 and times[i]['s'] == 0:
            dfs(i)
    else:
        time += 1
        times[u]['f'] = time

for i in range(N):
    if times[i]['s'] == 0:
        dfs(i)

for i, time in enumerate(times):
    print(i + 1, *time.values())

Submission status: Accepted

Solution code:
from collections import deque

n = int(input())

g = [deque([]) *n for _ in range(n)]

for i in range(n):
    u, k, *V = list(map(int, input().split()))
    V.sort()
    for v in V:
        g[u-1].append(v-1)
        # g[v-1].append(u-1)

time = 0
arrive_time = [-1] * n
finish_time = [-1] * n
def dfs(v):
    global time
    time += 1
    stack = [v]
    arrive_time[v] = time
    while stack:
        v = stack[-1]
        if g[v]:
            w = g[v].popleft()
            if arrive_time[w] < 0:
                time += 1
                arrive_time[w] = time
                stack.append(w)
        else:
            time += 1
            finish_time[v] = time
            stack.pop()

    return [arrive_time, finish_time]

for i in range(n):
    if arrive_time[i] < 0:
        ans = dfs(i)

for j in range(n):
    temp = [j+1, ans[0][j], ans[1][j]]
    print(*temp)

Submission status: Accepted

Solution code:
n = int(input())
M = [[0]*n for _ in range(n)]

for _ in range(n):
    u, k, *V = map(int, input().split())
    if k == 0:
        continue
    else:
        for v in V:
            M[u-1][v-1] = 1

color = ['White']*n

time = 0
d = [0]*n
f = [0]*n
def dfs_visit(u=0):
    global time
    color[u] = 'Gray'
    time += 1
    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]))


dfs()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10 ** 9)

N = int(input())
graph = list()
for i in range(N):
  x = list(map(int, input().split()))
  graph.append(x[2:])

start = [0] * N
end = [0] * N
visited = [False] * N
time = 0
def dfs(n):
  if visited[n]:
    return
  visited[n] = True
  global time
  time += 1
  start[n] = time
  for i in graph[n]:
    dfs(i-1)
  time += 1
  end[n] = time

for i in range(N):
  dfs(i)
for i in range(N):
  print(i+1, start[i], end[i])

Submission status: Accepted

Solution code:
n = int(input())
trees = [[]]
for i in range(n):
    edges = []
    s = list(map(int, input().split()))
    num = s[1]
    if s[1] != 0:
        edges = s[2:2+num]
    trees.append(edges)

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


def dfs(x, i=0):
    for y in trees[x]:
        if d[y] != 0:
            continue
        d[y] = i
        i += 1
        i = dfs(y, i)
    f[x] = i
    i += 1
    return i


i = 1
for j in range(1, n+1):
    if d[j] != 0:
        continue
    else:
        d[j] = i
        i += 1
    i = dfs(j, i)
for i in range(1, n+1):
    print(i, d[i], f[i])

Submission status: Accepted

Solution code:
n = int(input())

from collections import deque

graph = [deque([]) for _ in range(n+1)]

for _ in range(n):
    u, k, *v = [int(x) for x in input().split()]

    v.sort()
    for i in v:
        graph[u].append(i)
    
arrive = [-1 for i in range(n+1)]
finish = [-1 for i in range(n+1)]

times = 0

def dfs(v):
    global times
    times += 1
    arrive[v] = times
    stack = [v]
    
    while stack:
        v = stack[-1]
        if graph[v]:
            w = graph[v].popleft()
            if arrive[w] == -1:
                times += 1
                arrive[w] = times
                stack.append(w)
        else:
            times += 1
            finish[v] = times
            stack.pop()
    return

for i in range(n):
    if arrive[i+1] == -1:
        dfs(i+1)

for j in range(n):
    tmp = [j+1, arrive[j+1], finish[j+1]]
    print(*tmp)

Submission status: Accepted

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

N = int(input())
WHITE = 0
GRAY = 1
BLACK = 2

M = [[0]*N for _ in range(N)]
color = [WHITE]*N  # colorの初期化は最初に行っておく。
d = [0]*N
f = [0]*N

def dfs_visit(u):
    global tt
    color[u] = GRAY
    tt += 1
    d[u] = tt # 最初の訪問
    for v in range(N):
        if M[u][v] == 0:
            continue
        if color[v] == WHITE:
            dfs_visit(v)
    color[u] = BLACK
    tt += 1
    f[u] = tt # 訪問の完了

def dfs():
    global tt
    tt = 0

    for u in range(N):
        if color[u] == WHITE:
            # 未訪問のuを始点として深さ優先探索
            dfs_visit(u)
    for u in range(N):
        print(str(u+1) + ' ' + str(d[u]) + ' ' + str(f[u]))
for _ in range(N):
    u, k, *vv = input().split()
    u = int(u)-1  # 0オリジンにする
    k = int(k)    # kは使わない
    for v in vv:
        v = int(v)-1
        M[u][v] = 1
dfs()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10000000)
n = int(input())
G = [[] for i in range(n)]
d = [0 for i in range(n)]
f = [0 for i in range(n)]
color = [0 for i in range(n)]
stamp = 0

def dfs(u):
    global stamp
    if d[u]:
        return
    stamp += 1
    d[u] = stamp
    for v in G[u]:
        if color[v] != 0:
            continue
        color[v] = 1
        dfs(v)
    color[u] = 2
    stamp += 1
    f[u] = stamp

color[0] = 1
for i in range(n):
    inp = list(map(int, input().split()))
    u = inp[0]
    u -= 1
    k = inp[1]
    for j in range(k):
        v = inp[j+2]
        v -= 1
        G[u].append(v)
        #G[v].append(u)


for i in range(n):
    dfs(i)

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

Submission status: Accepted

Solution code:
n = int(input())
g = [[] for i in range(n)]
for i in range(n):
    g[i] = list(map(lambda x:int(x)-1,input().split()))[2:]

def dfs(v,t):
    t += 1
    d[v] = t
    for i in g[v]:
        if d[i]==-1:
            t = dfs(i,t)
    t += 1
    f[v] = t
    return t

t = 0
d = [-1]*n
f = [-1]*n

for i in range(n):
    if d[i]==-1:
        t = dfs(i,t)

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

Submission status: Accepted

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

d = [-1] * N
f = [-1] * N

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

def dfs(n):
    global d
    global f
    color = []
    for u in range(n):
        color.append(WHITE)
    tt = 0

    for u in range(n):
        if color[u] == WHITE:
            tt = dfs_visit(n, u, tt, color)
    
    for u in range(n):
        print(u+1, d[u], f[u])

n = int(input())

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

for i in range(n):
    I = list(map(int, input().split()))
    u = I[0] - 1
    k = I[1]
    for j in range(k):
        v = I[j+2] - 1
        M[u][v] = 1

#print(M)

dfs(n)

Submission status: Accepted

Solution code:
def DFS(num):
    global time
    time +=1
    color[num]="gray"
    D[num][0]=time
    for i in M[num]:
        if color[i]=="white":
            DFS(i)
    color[num]="black"
    time +=1
    D[num][1]=time


n=int(input())
M=[[] for _ in range(n+1)]
for i in range(n):
    for j in list(map(int,input().split()))[2:]:
        M[i+1].append(j)
color=["white" for _ in range(n+1)]
D=[[0,0] for _ in range(n+1)]
time=0
for i in range(n):
    if color[i+1]=="white":
        DFS(i+1)

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

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**7)
time = 0
def input():
    return sys.stdin.readline()
n = int(input())
G = [[]]
d = [0]*(n+1)
f = [0]*(n+1)
for _ in range(n):
    G.append(list(map(int,input().split()))[2:])
def dfs(e):
    global time
    d[e] = time
    for nexte in G[e]:
        if d[nexte] == 0:
            time += 1
            dfs(nexte)
    time += 1
    f[e] = time

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