hdu 5325 Crazy Bobo dfs

//    hdu 5325 Crazy Bobo
//
//    题目大意:
//        
//        给你一棵树,树上每一个节点都有一个权值w,选择尽可能多的节点,
//        这些节点相互联通,而且依照权值升序排序之后得到节点编号,
//        需相邻节点之间的随意节点都要大于较小的节点。
//        
//    解题思路:
//        对于每一对u,v,我们建一条这种边:权值小的像权值大的连一条边。
//        这样,问题就转化为求以u最小的权值为根的子树上点集的最大值。
//        dfs就可以。
//
//
//    感悟:
//        
//        多校的一道题目,当时并没有想出来怎么做。看了看题解。然后依照
//        自己的理解敲了一边,交一发,STACK_OVERFLOW,心想怎么可能呢?
//        然后依照题解交了一发,天真的没有复制拓展栈(当时无知的我并不知道)
//        交了一发还是STACK_OVERFLOW,心里就纳闷儿了,怎么可能呢?然后云集
//        了各方的题解,发现。。。要栈拓展。由于这题数据比較大。栈的空间须要
//        非常大,所以要拓展栈。

习得了pragma这项黑客技能,只是这是c++的,g++不能够 // 我也不太懂。仅仅是会Ctrl + C 和 Ctrl + V,看来还是得多掌握掌握技能。 // 继续加油吧!

!FIGHTING #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include <vector> using namespace std; const int MAX_N = 500009; vector<int> g[MAX_N]; int d[MAX_N]; int n; int w[MAX_N]; bool vis[MAX_N]; void dfs(int u){ vis[u] = 1; d[u] = 1; for (int i=0;i<g[u].size();i++){ int v = g[u][i]; if (!vis[v]){ dfs(v); } d[u] += d[v]; } } void print(){ for (int i=1;i<=n;i++){ printf("%d ",d[i]); } puts(""); } void input(){ for (int i=1;i<=n;i++){ scanf("%d",&w[i]); g[i].clear(); } for (int i = 1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); if (w[u] < w[v]) g[u].push_back(v); else if (w[v] < w[u]) g[v].push_back(u); } memset(vis,0,sizeof(vis)); } void solve(){ for (int i=1;i<=n;i++){ if (!vis[i]){ dfs(i); } } int mx = 0; for (int i=1;i<=n;i++){ mx = max(mx,d[i]); } printf("%d\n",mx); //print(); } int main(){ //freopen("1.txt","r",stdin); while(scanf("%d",&n)!=EOF){ input(); solve(); } }


posted @ 2017-06-04 10:20  wzzkaifa  阅读(120)  评论(0编辑  收藏  举报