大意: 给定n结点树, m个询问, 每次给出两个旅馆的位置, 求树上所有结点到最近旅馆距离的最大值

先考虑一些简单情形.

若旅馆只有一个的话, 显然到旅馆最远的点是直径端点之一

若树为链的话, 显然是直径端点或两旅馆的中点

这样的话思路就来了, 也就是说最远点要么是直径端点, 要么是到两旅馆距离差不超过1的点

实际求的时候并不需要求出具体在那个点取得最大, 只需简单分类讨论一下, 用RMQ预处理一下, O(1)回答询问

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <queue>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define pb push_back
using namespace std; const int N = 1e5+10, INF = 0x3f3f3f3f;
int n, m, r1, r2, mx;
vector<int> g[N];
int vis[N], fa[N], s[N], dep[N], no[N];
int Log[N], w[N], f[2][20][N]; int bfs(int x) {
memset(vis, 0, sizeof vis);
queue<int> q;
fa[x] = 0, vis[x] = 1, q.push(x);
while (!q.empty()) {
x = q.front();q.pop();
for (int y:g[x]) if (!vis[y]) {
vis[y] = 1, fa[y]=x, q.push(y);
}
}
return x;
} void dfs(int x, int fa, int d, int rt) {
dep[x]=d, no[x]=rt, w[rt] = max(w[rt], d);
for (int y:g[x]) if (!vis[y]&&y!=fa) {
dfs(y,x,d+1,rt);
}
} int RMQ(int l, int r, int p) {
if (l>r) return -INF;
int t = Log[r-l+1];
return max(f[p][t][l],f[p][t][r-(1<<t)+1]);
} int main() {
scanf("%d", &n);
REP(i,2,n) {
int u, v;
scanf("%d%d", &u, &v);
g[u].pb(v),g[v].pb(u);
}
r1 = bfs(1), r2 = bfs(r1);
memset(vis, 0, sizeof vis);
for (int i=r2; i; i=fa[i]) {
vis[i]=1, s[++*s]=i, no[i]=*s;
}
REP(i,1,*s) dfs(s[i],0,0,i);
Log[0] = -1;
memset(f,-63,sizeof f);
REP(i,1,*s) {
f[0][0][i]=w[i]+i,f[1][0][i]=w[i]-i;
Log[i] = Log[i>>1]+1;
}
REP(j,1,19) for (int i=1;i+(1<<j-1)<=*s; ++i) {
f[0][j][i] = max(f[0][j-1][i],f[0][j-1][i+(1<<j-1)]);
f[1][j][i] = max(f[1][j-1][i],f[1][j-1][i+(1<<j-1)]);
}
scanf("%d", &m);
REP(i,1,m) {
int x, y, ans;
scanf("%d%d", &x, &y);
int l=no[x], r=no[y];
if (l>r) swap(l,r),swap(x,y);
if (l==r) {
printf("%d\n", max(l-1,*s-l)+min(dep[x],dep[y]));
continue;
}
int mid = l+r-dep[x]+dep[y];
if (mid<=2*l) ans = max(r-1,*s-r)+dep[y];
else if (mid>=2*r) ans = max(l-1,*s-l)+dep[x];
else {
mid /= 2;
int L=max(l-1,RMQ(l+1,mid,0)-l)+dep[x];
int R=max(*s-r,RMQ(mid+1,r-1,1)+r)+dep[y];
ans = max(L,R);
}
printf("%d\n", ans);
}
}

Big Problems for Organizers CodeForces - 418D (贪心,直径)的更多相关文章

  1. Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

    题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...

  2. @codeforces - 418D@ Big Problems for Organizers

    目录 @description@ @solution@ @accepted code@ @details@ @description@ n 个点连成一棵树,经过每条边需要花费 1 个单位时间. 现给出 ...

  3. CF418D Big Problems for Organizers 树的直径、ST表

    题目传送门:http://codeforces.com/problemset/problem/418/D 大意:给出一棵有$N$个节点的树,所有树边边权为$1$,给出$M$次询问,每个询问给出$x,y ...

  4. CodeForces - 893D 贪心

    http://codeforces.com/problemset/problem/893/D 题意 Recenlty Luba有一张信用卡可用,一开始金额为0,每天早上可以去充任意数量的钱.到了晚上, ...

  5. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划

    There are n people and k keys on a straight line. Every person wants to get to the office which is l ...

  6. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心

    Arkady needs your help again! This time he decided to build his own high-speed Internet exchange poi ...

  7. CodeForces - 93B(贪心+vector<pair<int,double> >+double 的精度操作

    题目链接:http://codeforces.com/problemset/problem/93/B B. End of Exams time limit per test 1 second memo ...

  8. C - Ordering Pizza CodeForces - 867C 贪心 经典

    C - Ordering Pizza CodeForces - 867C C - Ordering Pizza 这个是最难的,一个贪心,很经典,但是我不会,早训结束看了题解才知道怎么贪心的. 这个是先 ...

  9. Codeforces 570C 贪心

    题目:http://codeforces.com/contest/570/problem/C 题意:给你一个字符串,由‘.’和小写字母组成.把两个相邻的‘.’替换成一个‘.’,算一次变换.现在给你一些 ...

随机推荐

  1. linux常用命令:whereis 命令

    whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息. 和find相比,whereis查找的速度非 ...

  2. Linux服务器---安装squid

    安装squid proxy就是软件代理或者代理服务器,而squid就是一种常用的proxy服务 1.安装squid [root@localhost wj]# rpm -qa | grep squid ...

  3. C++设计模式 之 “数据结构” 模式:Composite、Iterator、Chain of Resposibility

    "数据结构"模式 常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用.这时候,将这些特定数据结构封装在内部,在外部提供统一的接口, ...

  4. uboot 网络驱动模型

    原文:https://blog.csdn.net/zhouxinlin2009/article/details/45390065 UBOOT的PHYCHIP配置 PHYCHIP的配置位于 includ ...

  5. MBR记录

    mbr version: 1.6 boot code size: primary data size: extended data size: debug version: no bpb status ...

  6. 试着用React写项目-利用react-router解决跳转路由等问题(三)

    转载请注明出处:王亟亟的大牛之路 本来想一下子把路由的接下来的内容都写完的,但是今天白天开了会,传了些代码打了个包,就被耽搁了 这一篇来讲一下 IndexLink和 onlyActiveOnIndex ...

  7. 使用CLR Profiler查看C#运行程序的内存占用情况

    http://blog.csdn.net/wy3552128/article/details/8158938 https://msdn.microsoft.com/en-us/library/ff65 ...

  8. Facebook广告API系列 3 Ads Management

    Facebook广告API系列 3 Facebook marketing API有三大组成部分: Audience Management Ads Management Ads Insights 本篇介 ...

  9. mysql中时间计算函数SQL DATE_SUB()用法

    本文为博主原创,未经允许不得转载: 在写sql的时候,经常要在sql中传值时间,对时间进行计算并过滤.之前都是将时间在后台计算好,直接传值给sql, 今天发现,有一个更方便的sql函数,可以简化很多代 ...

  10. 有关keras(Ubuntu14.04,python2.7)

    第一部分:安装 由于我的电脑之前已经已经配置好了caffe,因此有关python的一切相关包都已经安装完成.因此,即使不用Anaconda安装依然很简单. sudo pip install tenso ...