AtCoder Context ABC 138 D KI

运行要求
运行时间限制: 2sec
内存限制: 1024MB

题目
有一个多叉树,上面有N个顶点,这N个顶点的标号伟1到N。这个树的顶点编号为1,第i个树枝(1<=i<=N-1),有顶点ai和顶点bi相连。
个顶点设置一个计数器,各个顶点的计数器默认为0。
从现在开始,进行Q次以下的操作。

  • 第j次操作(1<=j<=Q)的时候,顶点pj和顶点pj下属的顶点的计数器的值加上xi。

所有的操作结束后,求各个顶点的计数器值

要求

  • 2<=N<=200000
  • 1<=Q<=200000
  • 1<=ai<=bi<=N
  • 1<=pj<=N
  • 1<=xj<=10000
  • 所有的输入都为整数
  • 给定的图形是树结构

输入
输入都以以下标准从命令行输入

N Q
a1 b1
.
.
aN-1 bN-1
p1 x1
.
.
pQ xQ

输出
以顶点1,2,...N的顺序,输出所有顶点的计数器的值

例1
输入

4 3
1 2
2 3
2 4
2 10
1 100
3 1

输出

100 110 111 110

根据以上输入的值,可以构建以下树结构
AtCoder Context ABC 138 D KI_第1张图片

在各个操作中,相应的顶点的计数器的值会有如下过程的变化。

  • 操作1:顶点2为根的树,也就是顶点2,3,4,的计数器的值分别加10。这个时候顶点1,2,3,4的值分别为0,10,10,10,
  • 操作2:顶点1为根的树,也就是顶点1,2,3,4的计数器的值分别加100。这个时候顶点1,2,3,4的值分别为100,110,110,110
  • 操作3:顶点3为根的树,也就是顶点3的计数器加1。这个时候,顶点1,2,3,4的值分别为100,110,111,110

例2
输入

6 2
1 2
1 3
2 4
3 6
2 5
1 10
1 10

输出

20 20 20 20 20 20

解题思路

读懂题目

1. 多叉树上面有N个顶点。i为树枝的编号并且满足1<=i<=N-1。
总结一下条件就是有N的顶点有N-1个树枝

2. 以例2为例,节点上是有值的
AtCoder Context ABC 138 D KI_第2张图片

3.每个Parent节点的值都会堆积到它的子节点的值。

4.每个节点的值事先都已经准备好了

5. 节点上可以有多个值

6.方法

方法1:从最上级的根节点做dfs遍历,Parent节点要把自身的值传递到下面的节点。当节点遍历到自身的时候,自己的值要加上Parent节点传来的值
AtCoder Context ABC 138 D KI_第3张图片

方法2:从最上级的根节点做dfs遍历,Parent节点要把自身的值传递到下面的节点。当节点遍历到自身的时候,自己的值要加上Parent节点传来的值
AtCoder Context ABC 138 D KI_第4张图片

5.输出的值为各个节点的信息,把这些节点的信息做成一个list,根据节点的编号,一次写入

代码
这里写基于bfs遍历的AC代码

from sys import setrecursionlimit
setrecursionlimit(100000)
from collections import deque

S = input().split(" ")
N = int(S[0])
Q = int(S[1])

arr = []
prr = []
for i in range(N-1):
    S = input().split(" ")
    ar = [int(S[0]),int(S[1])]
    arr.append(ar)

for i in range(Q):
    S = input().split(" ")
    pr = [int(S[0]), int(S[1])]
    prr.append(pr)



def prepare(n, q, arr, prr):
    links = [[] for _ in range(n)]
    values = [0 for _ in range(n)]
    finalValues = [0 for _ in range(n)]
    for ar in arr:
        start = ar[0] - 1
        end = ar[1] - 1
        links[start].append(end)
        links[end].append(start)

    for pr in prr:
        i = pr[0] - 1
        x = pr[1]
        values[i] += x

    return links, values, finalValues


links, values, finalValues = prepare(N, Q, arr, prr)


def bfs():
    q = deque()
    q.append((0,-1,0))
    while len(q) > 0:
        currentNode,parentNode,parentAccumulate = q.popleft()
        parentAccumulate += values[currentNode]
        finalValues[currentNode] += parentAccumulate
        childNodes = links[currentNode]
        for ch in childNodes:
            if ch == parentNode:
                continue
            q.append((ch,currentNode,finalValues[currentNode]))

bfs()
print(*finalValues)

基于dfs遍历的AC代码,直接RE掉了。为了方便大家交流,贴上代码

from sys import setrecursionlimit

setrecursionlimit(100000)

S = input().split(" ")
N = int(S[0])
Q = int(S[1])

arr = []
prr = []
for i in range(N - 1):
    S = input().split(" ")
    ar = [int(S[0]), int(S[1])]
    arr.append(ar)

for i in range(Q):
    S = input().split(" ")
    pr = [int(S[0]), int(S[1])]
    prr.append(pr)


def prepare(n, q, arr, prr):
    links = [[] for _ in range(n)]
    values = [0 for _ in range(n)]
    lineStates = [-1 for _ in range(n)]
    finalValues = [0 for _ in range(n)]
    for ar in arr:
        start = ar[0] - 1
        end = ar[1] - 1
        links[start].append(end)
        links[end].append(start)

    for pr in prr:
        i = pr[0] - 1
        x = pr[1]
        values[i] += x

    return links, values, lineStates, finalValues


links, values, lineStates, finalValues = prepare(N, Q, arr, prr)


def dfs(currentNode, arr, parrentAccumulate):
    childNodes = links[currentNode]
    parrentAccumulate += values[currentNode]
    finalValues[currentNode] = parrentAccumulate
    lineStates[currentNode] = 1
    for ch in childNodes:
        if lineStates[ch] == -1:
            dfs(ch, arr, parrentAccumulate)


dfs(0, links, 0)
print(*finalValues)

你可能感兴趣的:(python)