题目
已知拥有N个顶点的树。该树的第i条边上的两个节点是ui和vi,长度为wi。你需要在满足以下的条件下,将树上的所有节点涂上黑色和白色。(可以将所有的顶点都涂上同样的颜色)。

要求
所有涂有相同颜色的节点,它们之间的距离必须是偶数

条件

  • 所有输入的数都为整数
  • 1<=N<=100000
  • 1<=ui<=vi<=N
  • 1<=Wi<=1000000000

输入
要求以下面的方式输入

N
u1 v1 w1
u2 v2 w2
.
.
.
uN-1 vN-1 wN-1

输出
把满足题目条件的N个点的涂鸦情况一行一行地输出。
对于i行的话,顶点i是白色的话输出0,顶点i是黑色的话,输出1
如果满足条件的情况有多个的话,输出任意一种都可以

例1
输入

3
1 2 2
2 3 1

输出

0
0
1

例2
输入

5
2 5 2
2 3 10
1 3 8
3 4 2

输出

1
0
1
0
1

解题思路

读懂题目

首先对于例2来说,树是长这样的
树.png

可以看到有5个顶点,4条线。条件中也可以看出有N个顶点,N-1条线。也就是说,不可能形成一个封闭的环路!

点个点之间距离的计算方法
对于点5和点4的距离。我们可以看到距离是2+10+2=14
这是我们直观的解法
但是自然界中还存在另外一个解法
点5和点4的距离P,可以看作
A:点1到点5的距离
B:点1到点4的距离
C:点1到点3的距离

P = A+B-2*C

这里
A = 8+10+2
B = 8+2
C = 8
P = 20 + 10 - 2*8 = 14

这里的C是4,5的父节点。

我们可以取任意一个点为顶点
这里我们取点1为顶点
如果我们取3为顶点的话,会得到同样的结果

点和点之间的距离公式化
我们选择顶点为P
计算点A和点B的距离

推断1.png

推断2.png

我们可以由上图看到,
A到B的距离=PA+PB -2*PC
其中2*PC必定是偶数,这在求奇偶性的时候可以忽略
A,B两个点之间的距离如果要求是偶数,那么要么PA,PB为偶,要么PA,PB为奇。

我们可以规定
PA,PB都为偶数的时候,A,B为白色
PA,PB都为奇数的时候,A,B为黑色
或者
PA,PB都为偶数的时候,A,B为黑色
PA,PB都为奇数的时候,A,B为白色

这样就能满足同色节点之间的距离是偶数这样的要求了

求每个节点到顶点的距离
我们规定第一个点位顶点,求每个点离第一个点距离
这里要用到dfs算法
关于dfs算法,这篇文章有详细的描述。这里就不再过多叙述了
简单来说就是要递归

BFS和DFS算法

代码

import sys
sys.setrecursionlimit(20000000)
def prepare(n,arr):
    nodeArr = [[] for i in range(n)]
    for ar in arr:
        nodeArr[ar[0]-1].append([ar[1]-1,ar[2]])
        nodeArr[ar[1]-1].append([ar[0]-1,ar[2]])
    return nodeArr

def dfs(currentNode,distance):
    res[currentNode] = distance
    for next in nodeArr[currentNode]:
        nextNode = next[0]
        nextNodeDistance = next[1]
        if res[nextNode] == -1:
            dfs(nextNode,distance + nextNodeDistance)


n = int(input())

arr = []

for i in range(n-1):
    arr.append([int(s) for s in input().split(" ")])

nodeArr = prepare(n, arr)


if n == 1:
    print(1)
else:
    res = [-1 for i in range(n)]

    dfs(0,0)

    result = [(re % 2) for re in res]

    for re in res:
        print(re % 2)

题外话

sys.setrecursionlimit(20000000)

这个不加的话,Atcoder提交测试的时候runtime error的报错


伟大不DIAO
1 声望1 粉丝

Done is better than perfect