hdu 5325 Crazy Bobo 附上证明 Multi-University Training Contest 3

来源:互联网 发布:ubuntu怎么装输入法 编辑:程序博客网 时间:2024/06/05 23:49

Crazy Bobo

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1237    Accepted Submission(s): 373


Problem Description
Bobo has a tree,whose vertices are conveniently labeled by 1,2,...,n.Each node has a weightwi. All the weights are distrinct.
A set with m nodes v1,v2,...,vm is a Bobo Set if:
- The subgraph of his tree induced by this set is connected.
- After we sort these nodes in set by their weights in ascending order,we get u1,u2,...,um,(that is,wui<wui+1 for i from 1 to m-1).For any node x in the path from ui to ui+1(excludingui and ui+1),should satisfy wx<wui.
Your task is to find the maximum size of Bobo Set in a given tree.
 

Input
The input consists of several tests. For each tests:
The first line contains a integer n (1n500000). Then following a line contains n integers w1,w2,...,wn (1wi109,all the wi is distrinct).Each of the following n-1 lines contain 2 integers ai and bi,denoting an edge between vertices ai and bi (1ai,bin).
The sum of n is not bigger than 800000.
 

Output
For each test output one line contains a integer,denoting the maximum size of Bobo Set.
 

Sample Input
73 30 350 100 200 300 4001 22 33 44 55 66 7
 

Sample Output
5
 

Author
ZSTU
 

Source
2015 Multi-University Training Contest 3


Crazy Bobo
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1237 Accepted Submission(s): 373



Problem Description

Bobo has a tree,whose vertices are conveniently labeled by 1,2,...,n.Each node has a weight wi. All the weights are distrinct.
A set with m nodes v1,v2,...,vm is a Bobo Set if:
- The subgraph of his tree induced by this set is connected.
- After we sort these nodes in set by their weights in ascending order,we get u1,u2,...,um,(that is,wui<wui+1 for i from 1 to m-1).For any node x in the path from ui to ui+1(excluding ui and ui+1),should satisfy wx<wui.
Your task is to find the maximum size of Bobo Set in a given tree.





Input

The input consists of several tests. For each tests:
The first line contains a integer n (1≤n≤500000). Then following a line contains n integers w1,w2,...,wn (1≤wi≤109,all the wi is distrinct).Each of the following n-1 lines contain 2 integers ai and bi,denoting an edge between vertices ai and bi (1≤ai,bi≤n).
The sum of n is not bigger than 800000.





Output

For each test output one line contains a integer,denoting the maximum size of Bobo Set.




Sample Input

7
3 30 350 100 200 300 400
1 2
2 3
3 4
4 5
5 6
6 7





Sample Output

5





Author

ZSTU




Source

2015 Multi-University Training Contest 3

第一次写错了几句话






题意:题目先给出一棵树,每个点都有权值,且各不相同,要你求符合条件的最大子树(包含结点最多),
所需满足的条件,对于所选子树的点 进行权值排序(从小到大)得到u1,u2,...,um,对于(1<=i<=m-1)的i
要求从点ui到点ui+1的道路上的结点权值比这两点都小。


证明:看人很多人的答案,大致的答案是对于已有的边,建立从权值大的点到权值小的点的有向边。(亦有从小到大的),然后ans=max( 能到达点i的点数  ) (i=1,...,n);
 
我的思考:
首先要求相邻权值的点所构成的path上的结点权值比这两点要小,这个条件不好思考,不妨反过来,先找一个权值小的点,再到两边找权值都比它大的点。

那么先找到一个点,这个点是某个子树中结点权值最小的点,然后我们求出以这个结点为最小权值点且满足条件的最大子树。(后简写为最小点,最大子树)

以图为例:
先找到结点1:结点1是最小点,那么向两边找比他大且与之相连的点2,3,自然形象地连出两条有向边1->2,1->3;

对于每个结点向下找,不能加入比它小的结点:若w[1]<w[a1]&&w[a1]>w[x],对于x,有与它权值相邻的点less和more,分别比他小和大,假如w[x]<w[1],与点1最小不符;
假如w[x]>w[1],那么less在a[1]左边,less与x道路上有点a1,权值比他们都大,不符题意。









对于每个结点向下找,可以加入比它大的结点:
假如加入结点2后,再加入比它大的结点4,我们考虑4对子树的影响,某个点的less可能变为点4,某个点more可能变为点4,
假如4的less是2,4和2中间没有点,符合,假如4的less不是2,而在1、3、7、8、9中,设为y,那么如果按照每个点加入比它大的结点,那么从4到y,中间的结点比4和y都小,符合题意,
4的more一定在1、3、7、8、9中,设为y,那么如果按照每个点加入比它大的结点,那么从4到y,中间的结点比4和y都小,符合题意。
所以对于每个结点向下找,可以加入比它小的结点:


这就是子树的找法,对于每条边,建立从权值小的点到权值大的点的有向边,对于每个点,找到从它出发最多能到达多少点(+自身)


#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<climits>#include<queue>#include<vector>#include<map>#include<sstream>#include<set>#include<stack>#include<utility>#pragma comment(linker, "/STACK:102400000,102400000")#define PI 3.1415926535897932384626#define eps 1e-10#define sqr(x) ((x)*(x))#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)#define  lson   num<<1,le,mid#define rson    num<<1|1,mid+1,ri#define MID   int mid=(le+ri)>>1#define zero(x)((x>0? x:-x)<1e-15)using namespace std;const int INF =0x3f3f3f3f;const int maxn= 500000+20   ;//const int maxm=    ;//const int INF=    ;//typedef long long ll;//ifstream fin("input.txt");//ofstream fout("output.txt");//fin.close();//fout.close();//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);int n;int w[maxn];vector<int >  nex[maxn];int dp[maxn];int DP( int here ){    if(dp[here]!=-1)  return dp[here];    int & ans=dp[here];    ans=1;    for(int i=0;i<nex[here].size();i++)    {        int & there= nex[here][i];        if(  w[there]<w[here]  )  continue;        ans+=DP(there);    }    return ans;}int main(){      int i,j;int x,y;      while(~scanf("%d",&n))      {          memset(dp,-1,sizeof dp);          for(int i=1;i<=n;i++)          {              nex[i].clear();          }          FOR1(i,n)  scanf("%d",&w[i]);          FOR1(i,n-1)          {              scanf("%d%d",&x,&y);              if( w[x]>w[y] )  nex[y].push_back(x);              else             nex[x].push_back(y);          }          int maxi=-1;          for(int i=1;i<=n;i++)              maxi=max(DP(i),maxi);            printf("%d\n",maxi);      }    return 0;}













0 0