解题思路: 一般来说树的题目可以考虑用递归算法解决,不是必须使用图结构的算法,比如树结构的两点最近距离只要找到两点公共祖先就能得到。但这个题目没有明确树根,也不明确边的方向(边方向由值决定)。所以还是用图结构的关键路径算法处理好一些。
关键路径算法和拓扑排序算法的唯一区别就是在拓扑过程中增加一条判断路径最大长度的语句。
#include <iostream>//ASI
#include<vector>
#include<queue>
typedef long long ll;
using namespace std;
int n,a[100005],d[100005],dp[100005],ans;//dp记录路径长度,d记录入度
vector<int>e[100005];
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int i,j,x,y;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<n;i++)
{
cin>>x>>y;
if(a[x]<a[y])
e[x].push_back(y),d[y]++;
else if(a[x]>a[y])
e[y].push_back(x),d[x]++;
}
queue<int>q;
for(i=1;i<=n;i++) //开始拓扑排序
if(!d[i])
q.push(i);
while(q.size())
{
int t=q.front();
q.pop();
for(i=0;i<e[t].size();i++)
{
y=e[t][i];
dp[y]=max(dp[y],dp[t]+1);//拓扑排序和关键路径区别之处,尝试发现更长的路径
ans=max(ans,dp[y]);
d[y]--;
if(!d[y])
q.push(y);
}
}
cout<<ans+1;
return 0;
}