HDU 5325 Crazy Bobo(深搜)

题意:给一个n,接着输入n个数,表示n个点的值,接着输入n-1条边形成一个生成树

问最大有多少个点的集合使得该集合内的所有点都满足如下:对于集合内点大小相邻的两个点,该两点之间经过的所有点的大小都小于该两点

eg  7

3 30 350 100 200 300 400

1 2 2 3 3 4 4 5 5 6 6 7

该无向图可表示为1——2——3——4——5——6——7

  取点6对于集合(3-7)来说,正好比他大的点为点3,且他们之间的所有点的

大小都小于该两点,满足条件

  同理取该集合内的其他点也满足条件

所有这个集合所有点满足条件,所以最大值为5(计算其他集合发现没有更大的集合满足上述条件)


分析:该题可以转换为,建有向图,对于一条边点值小的指向大的边,求由一

个点出发可以走过的最多的点数

如样例图为1->2->3<-4->5->6->7 当取点4时能经过5个点


注意:用深搜写要手动扩栈,并且要有C++交,不然会RE暴栈,用bfs写不会

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#pragma comment(linker,"/STACK:102400000,102400000")  //手动扩栈
using namespace std;
const int maxn = 5e5+5;
int E = 0;
int w[maxn];
int num[maxn];
int pnt[maxn*2],nxt[maxn*2],head[maxn*2];
void add(int u,int v)                   //邻接表
{
    nxt[E]=head[u];
    pnt[E]=v;
    head[u]=E++;
}
void dfs(int u){            //深搜
    num[u]++;
    for(int i=head[u];i!=-1;i=nxt[i]){
        int v=pnt[i];
        if(!num[v]) dfs(v);
        num[u]+=num[v];     //加上邻接点走过的个数
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        E=0;
        memset(head,-1,sizeof(head));
        memset(num,0,sizeof(num));
        for(int i=1;i<=n;i++) scanf("%d",&w[i]);
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            if(w[u]<w[v]) add(u,v);
            else add(v,u);
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            if(!num[i]) dfs(i);
            ans=max(ans,num[i]);    //求最大值
        }
        printf("%d\n",ans);
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值