大意: 给定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常用命令:/etc/group文件详解

    Linux /etc/group文件与/etc/passwd和/etc/shadow文件都是有关于系统管理员对用户和 用户组管理时相关的文件.linux /etc/group文件是有关于系统管理员对用 ...

  2. Linux中Postfix邮件发送配置(三)

    部署DNS服务器 postfix根据域名和地址做一个MX记录,A记录,PTR记录(一般在互联网上邮件服务器都要反解,没有PTR记录会认为是垃圾邮件) $ service iptables stop $ ...

  3. 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理

    转:http://blog.csdn.net/suhuaiqiang_janlay/article/details/60466333 本人找几篇讲得好的来整理一下. (1)问题的由来: (2)动态ip ...

  4. TED #09# You don't have to be an expert to solve big problems

    Tapiwa Chiwewe: You don't have to be an expert to solve big problems Collection noticed a haze hangi ...

  5. C++设计模式 之 “状态变化” 模式:State、Memento

    “状态变化”模式 在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?“状态变化”模式为这一问题提供了一种解决方案. 典型模式 # state # m ...

  6. 02: DOM 实例

    1.1 Event 对象 <body> <a id="myAnchor" href="http://www.microsoft.com"> ...

  7. 08: CORS实现跨域请求

    目录: 1.1 cors跨域请求介绍 1.2 使用tornado实现 复杂请求 1.3 Django中使用django-cors-headers解决跨域问题 1.1 cors跨域请求介绍返回顶部 1. ...

  8. vijos 1096 津津的储存计划

    题目描述 Description 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同. 为了让津津学习如何储蓄,妈妈提出,津津可以 ...

  9. C#中基于流的XML文件操作笔记

    System.Xml.XmlReader和System.Xml.XmlWriters是两个抽象类,XmlReader提供了对于XML数据的快速,非缓存,只进模式的读取器,XmlWriter表示一个编写 ...

  10. MySQL命令行导出、导入数据库,备份数据库表

    MySQL导出数据库/数据表 1.首先,将你MySQL安装目录,例如C:\Program Files\MySQL\MySQL Server 5.7\bin添加到你的系统环境变量PATH中: 2.导出数 ...