http://acm.hdu.edu.cn/showproblem.php?pid=5325
7 3 30 350 100 200 300 400 1 2 2 3 3 4 4 5 5 6 6 7
5
/** hdu5325 树的思维题 题目大意:给定一颗树,每个点都有一个权值,求出一棵子树,权值递增排序,要求相邻权值两个点的路径上的点的权值都要比这两个权值小 解题思路:对于树上的每条边,对于Wu<Wv,连一条u到v的边,从每个点开始bfs,找出能遍历最多的点就是答案 */ #include <stdio.h> #include <algorithm> #include <iostream> #include <string.h> using namespace std; const int maxn=1000505; int head[maxn],ip; void init() { memset(head,-1,sizeof(head)); ip=0; } struct note { int v,next; }edge[maxn]; void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u];head[u]=ip++; } pair <int ,int > p[maxn]; int w[maxn],dp[maxn],n; int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d",&w[i]); p[i]=make_pair(w[i],i); } sort(p+1,p+n+1); init(); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } int ans=0; for(int i=n;i>=1;i--) { int u=p[i].second; dp[u]=1; for(int j=head[u];j!=-1;j=edge[j].next) { int v=edge[j].v; if(w[u]<w[v]) { dp[u]+=dp[v]; } } ans=max(ans,dp[u]); } printf("%d\n",ans); } return 0; }