hdu 5325 Crazy Bobo dfs

11 篇文章 0 订阅
//    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();
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值