POJ 3162 Walking Race 树的直径+线段树
来源:互联网 发布:制作毕业视频软件 编辑:程序博客网 时间:2024/06/06 00:53
题目链接
http://poj.org/problem?id=3162
题意
给定一颗含n个结点的树,求每个点能走到的最远距离,挑选连续的k天 最长与最短之差不超过m,求最大k
思路
先求树的直径,然后线段树维护
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<string>#include<queue>#include<stack>#include<math.h>#include<set>#include<map>#define ll long longusing namespace std;const int INF = ( 2e9 ) + 2;const ll maxn = 1e6+10;struct edge{ int v,w,next;} e[maxn*2];struct node{ int Max,Min; int l,r;}t[maxn*4];int head[maxn];int tot;int d[2][maxn],Max[maxn];bool vis[maxn];int n,m;void build(int root,int l,int r){ t[root].l=l; t[root].r=r; if(l==r) { t[root].Max=t[root].Min=Max[l]; return; } int mid=(l+r)>>1; build(2*root,l,mid); build(2*root+1,mid+1,r); t[root].Max=max(t[root*2].Max,t[root*2+1].Max); t[root].Min=min(t[root*2].Min,t[root*2+1].Min);}int query(int root,int ql,int qr,bool mode){ int l=t[root].l,r=t[root].r; if(l>=ql&&r<=qr) { if(mode)return t[root].Max; else return t[root].Min; } if(l>qr||r<ql)return 0; int mid = (l+r)>>1; if(qr<=mid) return query(2*root,ql,qr,mode); else if(ql>mid) return query(2*root+1,ql,qr,mode); else { if(mode) return max(query(2*root,ql,qr,mode),query(2*root+1,ql,qr,mode)); else return min(query(2*root,ql,qr,mode),query(2*root+1,ql,qr,mode)); }}void init(){ memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); tot=0; d[0][1]=0;}void add(int u,int v,int w){ e[tot].v=v; e[tot].w=w; e[tot].next=head[u]; head[u]=tot++;}// 连续的k天 最长与最短之差不超过mvoid dfs(int u,int *d){ vis[u]=true; for(int i=head[u]; i!=-1; i=e[i].next) { int v=e[i].v,w=e[i].w; if(vis[v])continue; d[v]=d[u]+w; dfs(v,d); }}int solve(){ dfs(1,d[0]); int mx=-INF,pos; memset(vis,0,sizeof(vis)); for(int i=1; i<=n; i++) if(mx<d[0][i]) { mx=d[0][i]; pos=i; } d[0][pos]=0; memset(vis,0,sizeof(vis)); dfs(pos,d[0]); mx=-INF; for(int i=1;i<=n;i++) if(mx<d[0][i]) { mx=d[0][i]; pos=i; } d[1][pos]=0; memset(vis,0,sizeof(vis)); dfs(pos,d[1]); for(int i=1;i<=n;i++) Max[i]=max(d[0][i],d[1][i]); build(1,1,n); int i=1,j=1; int ans=-INF; for(;j<=n;j++) { while(query(1,i,j,1)-query(1,i,j,0)>m)i++; ans=max(ans,j-i+1); } return ans;}int main(){ int u,v,w; while(~scanf("%d%d",&n,&m)) { init(); for(int i=2; i<=n; i++) { scanf("%d%d",&v,&w); add(i,v,w); add(v,i,w); } printf("%d\n",solve()); }}
阅读全文
0 0
- POJ 3162 Walking Race 树的直径+线段树
- POJ 3162Walking Race 树的直径加单调队列
- POJ 3162 Walking Race (DFS + 线段树)
- POJ 3162 Walking Race 树的直径+单调队列(其实暴力也可以>_<)
- 【树形DP】Poj 3162 Walking Race (DP_树形DP(线段树))
- POJ 3162Walking Race( 树形dp+线段树处理区间)
- POJ 3162 Walking Race——树形dp+尺取+线段树
- poj 3162 Walking Race
- poj 3162 Walking Race
- POJ 3162 Walking Race
- POJ 3162 Walking Race 笔记
- POJ 3162(TreeDP+单调队列)Walking Race
- POJ 3162 Walking Race 树形DP
- POJ 3162 Walking Race (树形DP)
- POJ 3162 - Walking Race(树形DP)
- POJ 3162 Walking Race (单调队列)@
- POJ 3162 Walking Race(单调队列或线段树加树型DP)
- POJ 3162 Walking Race(树形DP+单调队列)
- 1 异常的概述和体系结构: jvm处理异常的方式和try。。。Catch处理异常:异常的抛出:如何处理多个异常:Throwable的常用的方法:异常的分类 自定义异常:
- Probability
- 移动优先的跨终端web概述
- Linux网络编程——tcp并发服务器(I/O复用之select
- linux下devicetree中惯用的of函数
- POJ 3162 Walking Race 树的直径+线段树
- HDOJ2639(01背包第k最优解模板题)
- Java多线程系列-happens-before规则和as-if-serial语义
- LeetCode——152. Maximum Product Subarray
- 学习中遇到的中文乱码问题。
- 【SSLGZ 2793】2017年10月26日提高组T2 Deep(博弈)
- Django基本命令 静态文件配置 笔记
- codevs 1052 地鼠游戏 贪心
- 宿主机 Navicat 连接VMware Ubuntu 虚拟机 的MySQL 实现方法