码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5325 Crazy Bobo(深搜)

时间:2015-07-29 17:19:35      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

题意:给一个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;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 5325 Crazy Bobo(深搜)

标签:

原文地址:http://blog.csdn.net/sin_xf/article/details/47129367

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!