首页 > 试题广场 >

最大最小路

[编程题]最大最小路
  • 热度指数:1039 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}对于给定的无向无根树,第 i 个节点上有一个权值 w_i 。我们定义一条简单路径是好的,当且仅当:路径上的点的点权最小值小于等于 a ,路径上的点的点权最大值大于等于 b

\hspace{15pt}保证给定的 a < b ,你需要计算有多少条简单路径是好的。

输入描述:
\hspace{15pt}第一行输入三个整数 n, a, b\left(1 \leq n \leq 5 \times 10^5, 1 \leq a < b \leq 10^9\right) 代表节点数、给定的上下限。

\hspace{15pt}第二行输入 n 个整数 w_1, w_2, \dots, w_n\left(1 \leq w_i \leq 10^9\right) 代表每个节点的权值。

\hspace{15pt}此后 n - 1 行,每行输入两个整数 u, v\left(1 \leq u, v \leq n, u \neq v\right) 代表一条无向边连接树上 uv 两个节点。


输出描述:
\hspace{15pt}在一行上输出一个整数,代表好路径的条数。
示例1

输入

5 2 3
5 4 3 3 1
1 2
1 3
3 4
3 5

输出

4

说明

\hspace{15pt}对于这个样例,如下图所示。路径 2 \to 1 \to 3 \to 5 是好的,因为路径点权最小值 1 \leqq a 且点权最大值 5 \geqq b


\hspace{15pt}除此之外,以下路径也是好的:
\hspace{23pt}\bullet\,1 \to 3 \to 5
\hspace{23pt}\bullet\,3 \to 5
\hspace{23pt}\bullet\,4 \to 3 \to 5
import sys
inps = sys.stdin.read().split('\n')

from collections import deque
def count(n, inSet, tree):
    total = 0
    visited = [False] * n
    for i in range(n):
        if not visited[i] and inSet[i]:
            que = deque()
            que.append(i)
            _n = 1
            visited[i] = True
            while que:
                u = que.popleft()
                for v in tree[u]:
                    if not visited[v] and inSet[v]:
                        _n += 1
                        que.append(v)
                        visited[v] = True
            total += _n * (_n - 1) // 2
    return total

def main():
    n, a, b = map(int, inps[0].split(' '))
    ws = list(map(int, inps[1].split(' ')))
    tree = [[] for _ in range(n)]
    for uv in inps[2:-1]:
        u, v = map(int, uv.split(' '))
        tree[u - 1].append(v - 1)
        tree[v - 1].append(u - 1)
    total = n * (n - 1) // 2
    
    inA = [w > a for w in ws]
    inB = [w < b for w in ws]
    inAB = [a < w < b for w in ws]

    cntA = count(n, inA, tree)
    cntB = count(n, inB, tree)
    cntAB = count(n, inAB, tree)
    oup = total - (cntA + cntB - cntAB)
    print(oup)


if __name__ == '__main__':
    main()

发表于 2025-07-09 09:41:26 回复(0)
为啥使用深度优先搜索只能通过示例和一个例子
line = [int(item) for item in input().split(" ")]
node_num = line[0]
min_num = line[1]
max_num = line[2]
node_val = [int(item) for item in input().split(" ")]
node_tu = [[0] * node_num for i in range(node_num)]
for i in range(0, node_num - 1):
    line = [int(item) for item in input().split(" ")]
    node_tu[line[0]-1][line[1]-1] = 1
    node_tu[line[1]-1][line[0]-1] = 1

# print(node_tu)

resa = []


def get_next_path(node_tu, searched_path):
    node = searched_path[-1]
    res = []
    for i in range(node_num):
        if node_tu[node - 1][i] == 1 and i + 1 not in searched_path:
            res.append(i + 1)
    return res


def search_path(node_tu, searched_path, res):
    next_path = get_next_path(node_tu, searched_path)
    if not next_path:
        val_list = []
        for item in searched_path:
            val_list.append(node_val[item - 1])
        if min(val_list) <= min_num and max(val_list) >= max_num:
            temp = list(reversed(searched_path))
            if searched_path not in res and temp not in res:
                res.append(searched_path)
    else:
        for node in next_path:
            search_path(node_tu, searched_path + [node], res)


for node in range(1,node_num+1):
    search_path(node_tu, [node,], resa)

print(len(resa))

发表于 2025-03-08 12:23:03 回复(1)