题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的区间,使得区间中的最大值与最小值的差不超过m。

思路:先找出树的直径的两个端点来,那么树当中的其它节点能走的最大距离一定是到这个两个点当中的其中一个的。所以三遍bfs就可以求出来这个最远的距离,那么,这个最远的距离求出来之后再用两个单调队列来维护最大值和最小值。

/*************************************************************************
> File Name: poj_3162.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年09月05日 星期六 14时00分47秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL;
const int maxn = 1e6 + ;
int tot, head[maxn];
struct Edge {
int to, next, w;
}edge[maxn * ];
typedef pair<int, int> pii;
int dis1[maxn], dis2[maxn], dis[maxn];
void init()
{
tot = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
int pos, maxx;
bool vis[maxn];
void bfs(int u, int *dist)//从u点开始搜索到各个点的距离,保存在dist当中
{
maxx = ;
queue<pii> Q;
memset(vis, false, sizeof(vis));
pii cur, nex;
cur.first = u; cur.second = ;
vis[u] = true;
dist[u] = ;
Q.push(cur);
while (!Q.empty())
{
cur = Q.front();
Q.pop();
for (int i = head[cur.first]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (vis[v]) continue;
vis[v] = true;
nex.first = v; nex.second = cur.second + edge[i].w;
dist[v] = nex.second;
if (maxx < nex.second)
{
maxx = nex.second;
pos = v;//直径的一个端点保存在pos当中
}
Q.push(nex);
}
}
}
int Q_max[maxn], Q_min[maxn];
int n, m;
int solve()//用两个单调队列分别维护最大值和最小值
{
int ans = ;
int front1, front2, tail1, tail2, i, j;
front1 = front2 = ; tail1 = tail2 = ;
for (j = , i = ; i <= n; i++)
{
while (tail1 >= front1 && dis[Q_max[tail1]] <= dis[i]) tail1--;
Q_max[++tail1] = i; while (tail2 >= front2 && dis[Q_min[tail2]] >= dis[i]) tail2--;
Q_min[++tail2] = i; if (dis[Q_max[front1]] - dis[Q_min[front2]] > m)
{
ans = max(ans, i - j);
while (dis[Q_max[front1]] - dis[Q_min[front2]] > m)
{
j = min(Q_max[front1], Q_min[front2]) + ;
while (tail1 >= front1 && Q_max[front1] < j) front1++;
while (tail2 >= front2 && Q_min[front2] < j) front2++;
}
}
}
ans = max(ans, i - j);
return ans;
}
int main()
{
while (~scanf("%d %d", &n, &m))
{
int v, w;
init();
for (int i = ; i < n; i++)
{
scanf("%d %d", &v, &w);
addedge(i + , v, w);
addedge(v, i + , w);
}
bfs(, dis1);
bfs(pos, dis1);
bfs(pos, dis2);
for (int i = ; i <= n; i++)
dis[i] = max(dis1[i], dis2[i]);
printf("%d\n", solve());
}
return ;
}

POJ 3162 Walking Race(树的直径+单调队列)的更多相关文章

  1. POJ 3162 Walking Race(树形dp+单调队列 or 线段树)

    http://poj.org/problem?id=3162 题意:一棵n个节点的树.有一个屌丝爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...

  2. HDU 4123 Bob’s Race 树的直径+单调队列

    题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...

  3. POJ 3162 Walking Race (树的直径,单调队列)

    题意:给定一棵带边权的n个节点的树,首先要求出每个点的最长路,然后写成序列d[1],d[2]...d[n],然后求满足 区间最大值-区间最小值<=k 的最大区间长度为多少? 思路: 分两步进行: ...

  4. POJ 3162.Walking Race 树形dp 树的直径

    Walking Race Time Limit: 10000MS   Memory Limit: 131072K Total Submissions: 4123   Accepted: 1029 Ca ...

  5. POJ - 3162 Walking Race 树形dp 单调队列

    POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...

  6. 【题解】poj 3162 Walking Race 树形dp

    题目描述 Walking RaceTime Limit: 10000MS Memory Limit: 131072KTotal Submissions: 4941 Accepted: 1252Case ...

  7. HDU 4123 Bob's Race:树的直径 + 单调队列 + st表

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[ ...

  8. HDU 4123(树的直径+单调队列)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. POJ 3162 Walking Race 树形DP+线段树

    给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成 ...

随机推荐

  1. Flask_SqlAlchemy 1215, 'Cannot add f oreign key constraint'

    Flask_SqlAlchemy 1215, 'Cannot add f oreign key constraint'报错 sqlalchemy.exc.IntegrityError: (pymysq ...

  2. JSP HTML区别

    1.最简单的区别就是,HTML能直接打开,jsp只能发布到Tomact等服务器上才能打开2.定义上HTML页面是静态页面可以直接运行,JSP页面是动态页它运行时需要转换成servlet.3.他们的表头 ...

  3. 应用SVN(CentOS中搭建SVN服务器)

    简单介绍如何在虚拟机 CentOS 中,搭建 SVN 服务器. 软件版本信息 Vmware 10.0.0 build-1295980 CentOS 7.0-1406-x64 Java 1.7.0_67 ...

  4. 应用tomcat(Linux中安装)

    CentOS 7 中安装 tomcat. 下载 Tomcat Wget 下载 Tomcat Tomcat 官网中找到指定版本 Tomcat rpm 的 url 使用 wget url 下载 rpm , ...

  5. Help Me with the Game

    Help Me with the GameCrawling in process... Crawling failed Description Your task is to read a pictu ...

  6. h.264直接预测

    直接预测是B帧上一种独有的预测方式,其中直接预测又分为两种模式: 时域直接模式(temporal direct).空域直接模式(spatial direct). 在分析这两种模式之前,有一个前提概念需 ...

  7. WM_SIZE和WM_MOVE的函数体内容为什么不一样?

    搞不懂,要想一想- procedure TWinControl.WMSize(var Message: TWMSize); begin UpdateBounds; // 类函数 inherited; ...

  8. RR区间锁 不是唯一索引,即使区间内没值,也锁

    +--------- +---------------------------------------------------------------------------------------- ...

  9. ext3文件系统,reiserfs,xfs,jsf那种性能好点

    ext2 是一个旧的 Linux 档桉系统,没有日志功能. 启用的时间通常需要很久.目前有许多 日志型态 的档桉系统可以以更快的速度及更好的效率完成系统启用和检查. ext3 为 ext2 的日志版, ...

  10. POJ3126 Prime Path(BFS)

    题目链接. AC代码如下: #include <iostream> #include <cstdio> #include <cstring> #include &l ...