Buggy python submission (verdict: Time Limit Exceeded):
import bisect
import numpy as np

def search(l, val):
    a = bisect.bisect_left(l, val)
    b = bisect.bisect_right(l, val)
    return list(range(a, b))

def resolve():
    N = int(input())
    X = [list(map(int,input().split())) for _ in range(N-1)]
    # u番目の頂点, v番目の頂点, 距離w
    
    X0 = sorted(X, key=lambda x: x[1])
    X1 = sorted(X)
    X0np = np.array(X0)
    X1np = np.array(X1)

    # 未彩色は-1
    color = [-1] * N
    color[0] = 0

    q = [(1, color[0])]
    while len(q) > 0:
        q0 = q[0]
        q = q[1:]

        r0 = search(X0np[:, 1], q0[0])
        for r in r0:
            val = X0[r][0]
            if color[val-1] == -1:
                c = (q0[1] + X0[r][2]) % 2
                color[val-1] = c
                q.append((val, c))
        r1 = search(X1np[:, 0], q0[0])
        for r in r1:
            val = X1[r][1]
            if color[val-1] == -1:
                c = (q0[1] + X1[r][2]) % 2
                color[val-1] = c
                q.append((val, c))
    
    for c in color:
        print(c)
        
resolve()

Fixed submission:
from queue import Queue

N = int(input())
X = [list(map(int, input().split())) for _ in range(N-1)]
X = list(map(lambda x: (x[0]-1, x[1]-1, x[2]), X))
# [u番目の頂点, v番目の頂点, 距離w]
# インデックスは0,...,N-1

# 頂点iの隣接情報を保持
node = [[] for i in range(N)]
for x in X:
    u, v, w = x
    node[u].append((v, w))
    node[v].append((u, w))

# 頂点iの色, 未彩色は-1
color = [-1] * N

# 幅優先探索で全頂点の色を決定
# 頂点0の色を0とする
q = Queue()
color[0] = 0
q.put((0, color[0]))
while not q.empty():
    q0 = q.get()

    n = q0[0]
    c = q0[1]
    neighbors = node[n]
    for p in neighbors:
        if color[p[0]] == -1:
            color[p[0]] = (c + p[1]) % 2
            q.put((p[0], color[p[0]]))

for c in color:
    print(c)

Buggy python submission (verdict: Time Limit Exceeded):
import bisect
import numpy as np

def search(l, val):
    a = bisect.bisect_left(l, val)
    b = bisect.bisect_right(l, val)
    return list(range(a, b))

def resolve():
    N = int(input())
    X = [list(map(int,input().split())) for _ in range(N-1)]
    # u番目の頂点, v番目の頂点, 距離w
    
    X0 = sorted(X, key=lambda x: x[1])
    X1 = sorted(X)
    X0np = np.array(X0)
    X1np = np.array(X1)

    # 未彩色は-1
    color = [-1] * N
    color[0] = 0

    q = [(1, color[0])]
    while len(q) > 0:
        q0 = q[0]
        q = q[1:]

        r0 = search(X0np[:, 1], q0[0])
        for r in r0:
            val = X0[r][0]
            if color[val-1] == -1:
                c = (q0[1] + X0[r][2]) % 2
                color[val-1] = c
                q.append((val, c))
        r1 = search(X1np[:, 0], q0[0])
        for r in r1:
            val = X1[r][1]
            if color[val-1] == -1:
                c = (q0[1] + X1[r][2]) % 2
                color[val-1] = c
                q.append((val, c))
    
    for c in color:
        print(c)
        
resolve()

Fixed submission:
from queue import Queue

N = int(input())
X = [list(map(int, input().split())) for _ in range(N-1)]
X = list(map(lambda x: (x[0]-1, x[1]-1, x[2]), X))
# [u番目の頂点, v番目の頂点, 距離w]
# インデックスは0,...,N-1

# 頂点iの隣接情報を保持
node = [[] for i in range(N)]
for x in X:
    u, v, w = x
    node[u].append((v, w))
    node[v].append((u, w))

# 頂点iの色, 未彩色は-1
color = [-1] * N

# 幅優先探索で全頂点の色を決定
# 頂点0の色を0とする
q = Queue()
color[0] = 0
q.put((0, color[0]))
while not q.empty():
    q0 = q.get()

    n = q0[0]
    c = q0[1]
    neighbors = node[n]
    for p in neighbors:
        if color[p[0]] == -1:
            color[p[0]] = (c + p[1]) % 2
            q.put((p[0], color[p[0]]))

for c in color:
    print(c)