题目
已知拥有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来说,树是长这样的
可以看到有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的距离
我们可以由上图看到,
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算法,这篇文章有详细的描述。这里就不再过多叙述了
简单来说就是要递归
代码
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的报错
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。