hdu 5325 Crazy Bobo (树形dp)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Crazy Bobo
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1077 Accepted Submission(s): 326
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.
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.
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
YY一下,想到只要保证一棵子树的节点到其所有的叶子节点的路径都是满足递增的,找出一棵这样的最大的子树即可。
先从下往上dp一遍,然后再从上往下,把父亲的信息传送下来,嗯,然后就以O(n)得到了所需要的结果
不过直接dfs会爆栈,所以得开一下栈,然后用C++提交
1 //##################### 2 //Author:fraud 3 //Blog: http://www.cnblogs.com/fraud/ 4 //##################### 5 #pragma comment(linker, "/STACK:102400000,102400000") 6 #include <iostream> 7 #include <sstream> 8 #include <ios> 9 #include <iomanip> 10 #include <functional> 11 #include <algorithm> 12 #include <vector> 13 #include <string> 14 #include <list> 15 #include <queue> 16 #include <deque> 17 #include <stack> 18 #include <set> 19 #include <map> 20 #include <cstdio> 21 #include <cstdlib> 22 #include <cmath> 23 #include <cstring> 24 #include <climits> 25 #include <cctype> 26 using namespace std; 27 #define XINF INT_MAX 28 #define INF 0x3FFFFFFF 29 #define MP(X,Y) make_pair(X,Y) 30 #define PB(X) push_back(X) 31 #define REP(X,N) for(int X=0;X<N;X++) 32 #define REP2(X,L,R) for(int X=L;X<=R;X++) 33 #define DEP(X,R,L) for(int X=R;X>=L;X--) 34 #define CLR(A,X) memset(A,X,sizeof(A)) 35 #define IT iterator 36 typedef long long ll; 37 typedef pair<int,int> PII; 38 typedef vector<PII> VII; 39 typedef vector<int> VI; 40 int Scan() { 41 int res=0, ch; 42 while(ch=getchar(), ch<'0'||ch>'9'); 43 res=ch-'0'; 44 while((ch=getchar())>='0'&&ch<='9') 45 res=res*10+ch-'0'; 46 return res; 47 } 48 void Out(int a) { 49 if(a>9) 50 Out(a/10); 51 putchar(a%10+'0'); 52 } 53 int w[500010]; 54 vector<int>G[500010]; 55 int dp[500010]; 56 void dfs1(int u,int fa){ 57 dp[u] = 1; 58 REP(i,G[u].size()){ 59 int v = G[u][i]; 60 if(v == fa)continue; 61 dfs1(v,u); 62 if(w[v] > w[u])dp[u] += dp[v]; 63 } 64 } 65 void dfs2(int u,int fa){ 66 if(fa!=-1){ 67 if(w[fa] > w[u])dp[u] += dp[fa]; 68 } 69 REP(i,G[u].size()){ 70 int v = G[u][i]; 71 if(v == fa)continue; 72 dfs2(v,u); 73 } 74 } 75 int main() 76 { 77 //ios::sync_with_stdio(false); 78 int n; 79 while(scanf("%d",&n)!=EOF){ 80 REP(i,n)w[i] = Scan(); 81 REP(i,n)G[i].clear(); 82 int u,v; 83 REP(i,n-1){ 84 u = Scan(); 85 v = Scan(); 86 u--;v--; 87 G[u].PB(v); 88 G[v].PB(u); 89 } 90 dfs1(0,-1); 91 dfs2(0,-1); 92 int ans = 0; 93 REP(i,n)ans = max(dp[i],ans); 94 Out(ans); 95 puts(""); 96 } 97 return 0; 98 } 99 100 101 /* 102 7 103 5 1 7 2 3 8 6 104 1 2 105 1 3 106 2 4 107 2 5 108 3 6 109 3 7 110 9 111 1 2 3 4 5 6 7 8 9 112 9 1 113 1 2 114 4 2 115 2 3 116 3 7 117 3 6 118 2 5 119 5 8 120 9 121 1 2 3 4 5 6 7 8 9 122 1 9 123 9 8 124 1 5 125 1 2 126 2 7 127 7 4 128 2 6 129 6 3 130 */