U74201 旅行计划 树上找链长度
Posted whff521
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了U74201 旅行计划 树上找链长度相关的知识,希望对你有一定的参考价值。
题目背景
珂朵莉放假了,她打算去唐山旅行。
题目描述
我们简单地把唐山的共 nn 个景点看成是一棵树,有 n-1n−1 条边将它们连接起来,每个景点有一个游览指数 v_ivi?。珂朵莉的假期时间不长,她只打算参观连续的恰好 kk 个景点。珂朵莉很可爱,所以她希望她所参观的景点里游览指数最低的景点的游览指数最高,她现在想知道其最高值是多少。
输入输出格式
输入格式:
第一行两个整数 n,k
接下来共 n−1 行每行两个整数 a b ,表示这两个景点相连
接下来 n 个整数 vi?
输出格式:
一个整数,如题描述
输入输出样例
输入样例
4 2 1 2 1 3 2 4 1 2 4 3
输出样例
2
说明
对于百分之三十的数据
n,k,v≤100
对于百分之六十的数据
n,k,v≤500
对于百分之百的数据
k≤n≤100000
1≤vi?≤1000000
这道题用二分枚举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;
以上是关于U74201 旅行计划 树上找链长度的主要内容,如果未能解决你的问题,请参考以下文章