zoukankan      html  css  js  c++  java
  • U74201 旅行计划 树上找链长度

    题目背景

    珂朵莉放假了,她打算去唐山旅行。

    题目描述

    我们简单地把唐山的共 nn 个景点看成是一棵树,有 n-1n1 条边将它们连接起来,每个景点有一个游览指数 v_ivi。珂朵莉的假期时间不长,她只打算参观连续的恰好 kk 个景点。珂朵莉很可爱,所以她希望她所参观的景点里游览指数最低的景点的游览指数最高,她现在想知道其最高值是多少。

    输入输出格式

    输入格式:

    第一行两个整数 n,k

    接下来共 n1 行每行两个整数 b ,表示这两个景点相连

    接下来 n 个整数 vi

    输出格式:

    一个整数,如题描述

    输入输出样例

    输入样例

    4 2
    1 2
    1 3
    2 4
    1 2 4 3
    输出样例
    2

    说明

    对于百分之三十的数据

    n,k,v100

    对于百分之六十的数据

    n,k,v500

    对于百分之百的数据

    kn100000

    1vi1000000

    这道题用二分枚举k上最小的最大值

    然后check()判断树上是否有一条符合条件的链长度>=k;

    用fir记录当前节点儿子中最长链长度,sec为当前节点儿子中第二长链,g[]为第一加第二+1等于当前节点为根节点时满足条件的最长链的长度(前提是当前节点满足条件)。

    思想就是这样;

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=100050;
    int pre[2*maxn],last[maxn],other[2*maxn],l;
    int n,k,val[maxn],ans,mid,qw;
    int fir[maxn],sec[maxn],g[maxn];
    void add(int x,int y)
    {
        l++;
        pre[l]=last[x];
        last[x]=l;
        other[l]=y;
    }
    
    void dfs(int u,int fa)
    {
        for(int p=last[u];p;p=pre[p])
        {
            int v=other[p];
            if(v==fa) continue;
            dfs(v,u);
            if(g[v]>fir[u])//儿子的最长链更新 当前节点的第一大链 
            {
                fir[u]=g[v];
            }
            else if(sec[u]<g[v])//不然看看第二长链 
            {
                sec[u]=g[v];
            }
        }
        if(val[u]>=mid&&sec[u]+fir[u]+1>=k)
        {
            qw=1;
        }
        if(val[u]>=mid) g[u]=fir[u]+1;//更新当前节点最长链 
        else g[u]=0;
    }
    
    int check()
    {
        qw=0;
        memset(g,0,sizeof(g));
        memset(fir,0,sizeof(fir));
        memset(sec,0,sizeof(sec));
        dfs(1,0);
        
        return qw;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&val[i]);
        }
        int l=0,r=100001;
        while(l<=r)
        {
         mid=(l+r)>>1;
            if(check())
            {
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    【转载】java调用C++写的DLL
    【转载】Java实现word转pdf
    【原创】由一件匪夷所思的事情所想到的
    【原创】不定字段的数据库表设计思路
    【原创】IBM Websphere 报错:JSPG0120E: 为 pageEncoding 属性和匹配 URI 模式的配置元素指定不同的值是非法的。
    weblogic <BEA-000438>
    svn报错 400 Bad Request
    实习技术知识点
    重写HashMap
    QUnit利用代理测试不同PHP开发服务器的json服务
  • 原文地址:https://www.cnblogs.com/WHFF521/p/11065979.html
Copyright © 2011-2022 走看看