Buggy python submission (verdict: Time Limit Exceeded):
# from collections import defaultdict
# dd = defaultdict(lambda: 0)

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

for i in range(N-1):
    u, v, w = [int(x) for x in input().split()]
    u -= 1
    v -= 1
    T[u][v] = w
    T[v][u] = w

opened = {0}
g0 = {0}
used = {0}

while len(opened) != 0:
    n = opened.pop()
    for n2 in T[n]:
        if n2 in g0:
            continue
        if n in g0:
            if T[n][n2] % 2 == 0:
                g0.add(n2)
        else:
            if T[n][n2] % 2 == 1:
                g0.add(n2)
        opened.add(n2)
        used.add(n2)

for i in range(N):
    print(0 if i in g0 else 1)






Fixed submission:
# from collections import defaultdict
# dd = defaultdict(lambda: 0)

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

for i in range(N-1):
    u, v, w = [int(x) for x in input().split()]
    u -= 1
    v -= 1
    T[u][v] = w
    T[v][u] = w

opened = {0}
g0 = {0}
used = {0}

while len(opened) != 0:
    n = opened.pop()
    for n2 in T[n]:
        if n2 in used:
            continue
        if n in g0:
            if T[n][n2] % 2 == 0:
                g0.add(n2)
        else:
            if T[n][n2] % 2 == 1:
                g0.add(n2)
        opened.add(n2)
        used.add(n2)

for i in range(N):
    print(0 if i in g0 else 1)

Buggy python submission (verdict: Time Limit Exceeded):
import sys


class Graph():

    def __init__(self, vertices):
        self.V = vertices
        self.graph = [[0 for column in range(vertices)]
                      for row in range(vertices)]

    def printSolution(self, dist):
        print
        "Vertex tDistance from Source"
        for node in range(self.V):
            print
            node, "t", dist[node]

    # A utility function to find the vertex with
    # minimum distance value, from the set of vertices
    # not yet included in shortest path tree
    def minDistance(self, dist, sptSet):

        # Initilaize minimum distance for next node
        # min = sys.maxint
        min = float("inf")

        # Search not nearest vertex not in the
        # shortest path tree
        for v in range(self.V):
            if dist[v] < min and sptSet[v] == False:
                min = dist[v]
                min_index = v

        return min_index

    # Funtion that implements Dijkstra's single source
    # shortest path algorithm for a graph represented
    # using adjacency matrix representation
    def dijkstra(self, src):

        dist = [float("inf")] * self.V
        dist[src] = 0
        sptSet = [False] * self.V

        for cout in range(self.V):

            # Pick the minimum distance vertex from
            # the set of vertices not yet processed.
            # u is always equal to src in first iteration
            u = self.minDistance(dist, sptSet)

            # Put the minimum distance vertex in the
            # shotest path tree
            sptSet[u] = True

            # Update dist value of the adjacent vertices
            # of the picked vertex only if the current
            # distance is greater than new distance and
            # the vertex in not in the shotest path tree
            for v in range(self.V):
                if self.graph[u][v] > 0 and sptSet[v] == False and \
                        dist[v] > dist[u] + self.graph[u][v]:
                    dist[v] = dist[u] + self.graph[u][v]

        # self.printSolution(dist)
        return dist


# Driver program

N = int(input())
g = Graph(N)

graph = [[0] * N for _ in range(N)]

# g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],
#            [4, 0, 8, 0, 0, 0, 0, 11, 0],
#            [0, 8, 0, 7, 0, 4, 0, 0, 2],
#            [0, 0, 7, 0, 9, 14, 0, 0, 0],
#            [0, 0, 0, 9, 0, 10, 0, 0, 0],
#            [0, 0, 4, 14, 10, 0, 2, 0, 0],
#            [0, 0, 0, 0, 0, 2, 0, 1, 6],
#            [8, 11, 0, 0, 0, 0, 1, 0, 7],
#            [0, 0, 2, 0, 0, 0, 6, 7, 0]
#            ];


L = []
for i in range(N - 1):
    u, v, w = [int(x) for x in input().split()]
    # L.append((u, v, w))
    # L.append((v, u, w))
    graph[u - 1][v - 1] = w
    graph[v - 1][u - 1] = w

g.graph = graph

dist = g.dijkstra(0);
# d = G.dijkstra(1, 2)

# print(dist)

for i in range(N):
    print(0 if dist[i] % 2 == 0 else 1)


Fixed submission:
# from collections import defaultdict
# dd = defaultdict(lambda: 0)

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

for i in range(N-1):
    u, v, w = [int(x) for x in input().split()]
    u -= 1
    v -= 1
    T[u][v] = w
    T[v][u] = w

opened = {0}
g0 = {0}
used = {0}

while len(opened) != 0:
    n = opened.pop()
    for n2 in T[n]:
        if n2 in used:
            continue
        if n in g0:
            if T[n][n2] % 2 == 0:
                g0.add(n2)
        else:
            if T[n][n2] % 2 == 1:
                g0.add(n2)
        opened.add(n2)
        used.add(n2)

for i in range(N):
    print(0 if i in g0 else 1)

Buggy python submission (verdict: Time Limit Exceeded):
import sys
import collections
from collections import Counter
from collections import deque
from collections import defaultdict
import itertools
from itertools import accumulate
from itertools import permutations
from itertools import combinations
from itertools import takewhile
from itertools import compress
import functools
from functools import reduce
import math
####from math import gcd
####from math import inf
from math import ceil
from math import floor
##from math import log10
##from math import log2
##from math import log
from math import factorial
import re
from functools import lru_cache

# @lru_cache(maxsize=1000)

# MOD = 10 ** 9 + 7

# N = int(input())
# A = [int(x) for x in input().split()]
# V = [[0] * 100 for _ in range(100)]

from collections import deque, namedtuple

# we'll use infinity as a default distance to nodes.
inf = float('inf')
Edge = namedtuple('Edge', 'start, end, cost')


def make_edge(start, end, cost=1):
    return Edge(start, end, cost)



class Graph:
    def __init__(self, edges):
        # let's check that the data is right
        wrong_edges = [i for i in edges if len(i) not in [2, 3]]
        if wrong_edges:
            raise ValueError('Wrong edges data: {}'.format(wrong_edges))

        self.edges = [make_edge(*edge) for edge in edges]

    @property
    def vertices(self):
        return set(
            sum(
                ([edge.start, edge.end] for edge in self.edges), []
            )
        )

    def get_node_pairs(self, n1, n2, both_ends=True):
        if both_ends:
            node_pairs = [[n1, n2], [n2, n1]]
        else:
            node_pairs = [[n1, n2]]
        return node_pairs

    def remove_edge(self, n1, n2, both_ends=True):
        node_pairs = self.get_node_pairs(n1, n2, both_ends)
        edges = self.edges[:]
        for edge in edges:
            if [edge.start, edge.end] in node_pairs:
                self.edges.remove(edge)

    def add_edge(self, n1, n2, cost=1, both_ends=True):
        node_pairs = self.get_node_pairs(n1, n2, both_ends)
        for edge in self.edges:
            if [edge.start, edge.end] in node_pairs:
                return ValueError('Edge {} {} already exists'.format(n1, n2))

        self.edges.append(Edge(start=n1, end=n2, cost=cost))
        if both_ends:
            self.edges.append(Edge(start=n2, end=n1, cost=cost))

    @property
    def neighbours(self):
        neighbours = {vertex: set() for vertex in self.vertices}
        for edge in self.edges:
            neighbours[edge.start].add((edge.end, edge.cost))

        return neighbours



    def dijkstra(self, source, dest):
        assert source in self.vertices, 'Such source node doesn\'t exist'

        distances = {vertex: inf for vertex in self.vertices}
        previous_vertices = {
            vertex: None for vertex in self.vertices
        }
        distances[source] = 0
        vertices = self.vertices.copy()

        while vertices:
            current_vertex = min(
                vertices, key=lambda vertex: distances[vertex])
            vertices.remove(current_vertex)
            if distances[current_vertex] == inf:
                break
            for neighbour, cost in self.neighbours[current_vertex]:
                alternative_route = distances[current_vertex] + cost
                if alternative_route < distances[neighbour]:
                    distances[neighbour] = alternative_route
                    previous_vertices[neighbour] = current_vertex

        path, current_vertex = deque(), dest
        while previous_vertices[current_vertex] is not None:
            path.appendleft(current_vertex)
            current_vertex = previous_vertices[current_vertex]
        if path:
            path.appendleft(current_vertex)

        return distances
        # return path


# graph = Graph([
#     ("a", "b", 7),  ("a", "c", 9),  ("a", "f", 14), ("b", "c", 10),
#     ("b", "d", 15), ("c", "d", 11), ("c", "f", 2),  ("d", "e", 6),
#     ("e", "f", 9)])
#
# print(graph.dijkstra("a", "e"))


N = int(input())

L = []
for i in range(N - 1):
    u, v, w = [int(x) for x in input().split()]
    L.append((u, v, w))
    L.append((v, u, w))
G = Graph(L)



d = G.dijkstra(1,2)

for i in range(1,N+1):
    print(0 if d[i]%2==0 else 1)




Fixed submission:
# from collections import defaultdict
# dd = defaultdict(lambda: 0)

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

for i in range(N-1):
    u, v, w = [int(x) for x in input().split()]
    u -= 1
    v -= 1
    T[u][v] = w
    T[v][u] = w

opened = {0}
g0 = {0}
used = {0}

while len(opened) != 0:
    n = opened.pop()
    for n2 in T[n]:
        if n2 in used:
            continue
        if n in g0:
            if T[n][n2] % 2 == 0:
                g0.add(n2)
        else:
            if T[n][n2] % 2 == 1:
                g0.add(n2)
        opened.add(n2)
        used.add(n2)

for i in range(N):
    print(0 if i in g0 else 1)