城市网络

链接:https://ac.nowcoder.com/acm/problem/13331
来源:牛客网

题目描述

有一个树状的城市网络(即 n 个城市由 n-1 条道路连接的连通图),首都为 1 号城市,每个城市售卖价值为 a_i 的珠宝。
你是一个珠宝商,现在安排有 q 次行程,每次行程为从 u 号城市前往 v 号城市(走最短路径),保证 v 在 u 前往首都的最短路径上。 在每次行程开始时,你手上有价值为 c 的珠宝(每次行程可能不同),并且每经过一个城市时(包括 u 和 v ),假如那个城市中售卖的珠宝比你现在手上的每一种珠宝都要优秀(价值更高,即严格大于),那么你就会选择购入。
现在你想要对每一次行程,求出会进行多少次购买事件。

输入描述:

第一行,两个正整数 n , q (2 ≤ n ≤ 10^5 , 1 ≤ q ≤ 10^5)。
第二行,n 个正整数 a_i (1 ≤ a_i ≤ 10^5) 描述每个城市售卖的珠宝的价值。
接下来 n-1 行,每行描述一条道路 x , y (1 ≤ x,y ≤ n),表示有一条连接 x 和 y 的道路。
接下来 q 行,每行描述一次行程 u , v , c (1 ≤ u,v ≤ n , 1 ≤ c ≤ 10^5)。

输出描述:

对于每次行程输出一行,为所购买次数。
示例1

输入

复制
5 4
3 5 1 2 4
1 2
1 3
2 4
3 5
4 2 1
4 2 2
4 2 3
5 1 5

输出

复制
2
1
1
0

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int s[100001];
int value[100001];
int tmp = 0;
void dfs(int u, int des, int val);
int main()
{
    int n, q;
    scanf("%d%d", &n, &q);
    for (int i = 1; i <= n; i++)
        scanf("%d", &value[i]);
    for (int i = 1; i < n; i++)
    {
        int parent, son;
        cin >> parent >> son;
        s[parent] += s[son];
        s[son] = parent;
    }
    for (int i = 1; i <= q; i++) {
        int u, des, val;
        tmp = 0;
        cin >> u >> des >> val;
        dfs(u, des, val);
        cout << tmp<<endl;
    }
    while (1);
}
void dfs(int u, int des, int val)
{
    if (u != des)
    {
        if (value[u] > val) {
            val = value[u];
            tmp++;
        }
        dfs(s[u], des, val);
    }
    if (value[u] > val)
        tmp++;
}

遇到的问题:emmm,其实也没什么难点,但还是要水一下,用数组构成一颗树跟并查集的构成是一样的,然后在用dfs就行

posted @ 2019-09-28 14:12  PYozo_free  阅读(298)  评论(0编辑  收藏  举报