大意: 给定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. SVN Error: Unreadable path encountered; access denied;

    最近在公司弄了版本库.将主代码丢到版本库后,想拉取新的分支.抛异常如下: SVN Error: Unreadable path encountered; access denied; 解决办法: 1. ...

  2. iOS &Android 项目 Jenkins持续集成

    背景:由于之前的jenkins机器软件环境较老(mac系统 和 Xcode版本等太低).设备性能也是比较差,编译相关脚本也不大适合目前业务,所以,跟infra部门重新申请了一台固定ip .高配的mac ...

  3. 立几个flag

    有时候会心血来潮想学一点东西,然后搞别的东西的时候就慢慢忘了.. 这里做个备忘录: 树分块/树上莫队 广义后缀自动机(大概这辈子都不会去学了) 带花树(如果我能学的动那个线代的随机算法就放弃这个) 模 ...

  4. 2018-2019-1 1723《程序设计与数据结构》第5&6&7周作业 总结

    作业地址 第五周作业: 提交情况如图: 第六周作业: 提交情况如图: 第七周作业: 提交情况如图: 作业问题 很多看上写的比较详细并且语言组织的也不错,我就这么随手一百度,搜出来了很多篇博客.(无奈) ...

  5. Linux虚拟内存和物理地址的理解【转】

    本文转载自:http://blog.csdn.net/dlutbrucezhang/article/details/9058583 在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中.这 ...

  6. hdu2552 (浮点数复杂运算的四舍五入)题解

    三足鼎立 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  7. HDU 4734 (数位DP)题解

    思路: dp[pos][pre]代表长度为pos的不大于pre的个数 #include<iostream> #include<cstdio> #include<cstri ...

  8. C#创建继承的窗体

    http://blog.csdn.net/chenyujing1234/article/details/7555369 关键技术 基窗体,实质上相当于面向对象编程中提到的基类,而继承窗体则是子类或派生 ...

  9. LOJ#2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On

    题目描述 译自 BalticOI 2011 Day1 T3「Switch the Lamp On」有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会.有 N×M 个这样 ...

  10. [SpringMVC] - 简单说明什么是SpringMVC

    M 代表 模型(Model)V 代表 视图(View) C 代表 控制器(controller) 模型是什么呢? 模型就是数据,就是dao,bean 视图是什么呢? 就是网页, JSP,用来展示模型中 ...