### 思路
1. **输入处理**:读取节点个数、点权和边。
2. **构建图**:将树转换为有向无环图(DAG),边的方向从点权小的指向点权大的。
3. **拓扑排序**:对DAG进行拓扑排序。
4. **动态规划**:使用动态规划求解最长路径。
### 细节
- **图的构建**:遍历所有边,根据点权大小确定边的方向。
- **拓扑排序**:使用Kahn算法或DFS进行拓扑排序。
- **动态规划**:初始化每个节点的最长路径长度为1,按照拓扑排序的顺序更新每个节点的最长路径长度。
### 伪代码
```plaintext
function longest_increasing_path(n, a, edges):
graph = build_graph(n, a, edges)
topo_order = topological_sort(graph)
dp = array of size n initialized to 1
for node in topo_order:
for neighbor in graph[node]:
if a[node] < a[neighbor]:
dp[neighbor] = max(dp[neighbor], dp[node] + 1)
return max(dp)
function build_graph(n, a, edges):
graph = adjacency list of size n
for u, v in edges:
if a[u-1] < a[v-1]:
graph[u-1].append(v-1)
else:
graph[v-1].append(u-1)
return graph
function topological_sort(graph):
in_degree = array of size n initialized to 0
for node in graph:
for neighbor in graph[node]:
in_degree[neighbor] += 1
queue = empty queue
for i in range(n):
if in_degree[i] == 0:
queue.push(i)
topo_order = empty list
while queue is not empty:
node = queue.pop()
topo_order.append(node)
for neighbor in graph[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.push(neighbor)
return topo_order
```
### C++代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>using namespace std;vector<vector<int>> build_graph(int n, const vector<int>& a, const vector<pair<int, int>>& edges) {vector<vector<int>> graph(n);for (const auto& edge : edges) {int u = edge.first - 1;int v = edge.second - 1;if (a[u] < a[v]) {graph[u].push_back(v);} else {graph[v].push_back(u);}}return graph;
}vector<int> topological_sort(const vector<vector<int>>& graph) {int n = graph.size();vector<int> in_degree(n, 0);for (const auto& neighbors : graph) {for (int neighbor : neighbors) {in_degree[neighbor]++;}}queue<int> q;for (int i = 0; i < n; ++i) {if (in_degree[i] == 0) {q.push(i);}}vector<int> topo_order;while (!q.empty()) {int node = q.front();q.pop();topo_order.push_back(node);for (int neighbor : graph[node]) {in_degree[neighbor]--;if (in_degree[neighbor] == 0) {q.push(neighbor);}}}return topo_order;
}int longest_increasing_path(int n, const vector<int>& a, const vector<pair<int, int>>& edges) {vector<vector<int>> graph = build_graph(n, a, edges);vector<int> topo_order = topological_sort(graph);vector<int> dp(n, 1);for (int node : topo_order) {for (int neighbor : graph[node]) {if (a[node] < a[neighbor]) {dp[neighbor] = max(dp[neighbor], dp[node] + 1);}}}return *max_element(dp.begin(), dp.end());
}int main() {int n;cin >> n;vector<int> a(n);for (int i = 0; i < n; ++i) {cin >> a[i];}vector<pair<int, int>> edges(n - 1);for (int i = 0; i < n - 1; ++i) {cin >> edges[i].first >> edges[i].second;}cout << longest_increasing_path(n, a, edges) << endl;return 0;
}