Big Problems for Organizers CodeForces - 418D (贪心,直径)
大意: 给定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 (贪心,直径)的更多相关文章
- Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]
题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...
- @codeforces - 418D@ Big Problems for Organizers
目录 @description@ @solution@ @accepted code@ @details@ @description@ n 个点连成一棵树,经过每条边需要花费 1 个单位时间. 现给出 ...
- CF418D Big Problems for Organizers 树的直径、ST表
题目传送门:http://codeforces.com/problemset/problem/418/D 大意:给出一棵有$N$个节点的树,所有树边边权为$1$,给出$M$次询问,每个询问给出$x,y ...
- CodeForces - 893D 贪心
http://codeforces.com/problemset/problem/893/D 题意 Recenlty Luba有一张信用卡可用,一开始金额为0,每天早上可以去充任意数量的钱.到了晚上, ...
- 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 ...
- 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 ...
- 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 ...
- C - Ordering Pizza CodeForces - 867C 贪心 经典
C - Ordering Pizza CodeForces - 867C C - Ordering Pizza 这个是最难的,一个贪心,很经典,但是我不会,早训结束看了题解才知道怎么贪心的. 这个是先 ...
- Codeforces 570C 贪心
题目:http://codeforces.com/contest/570/problem/C 题意:给你一个字符串,由‘.’和小写字母组成.把两个相邻的‘.’替换成一个‘.’,算一次变换.现在给你一些 ...
随机推荐
- python webdriver 从无到有搭建数据驱动自动化测试框架的步骤和总结
一步一步搭建数据驱动测试框架的过程和总结 跟吴老学了搭建自动化数据驱动的框架后,我在自己练习的时候,尝试从简单的程序进行一点一点的扩展和优化,到实现这个数据驱动的框架. 先说一下搭建自动化测试框架的目 ...
- 如何合并两个Git仓库
欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...
- 面试问题整理之python测试
1.下列哪个语句在Python中是非法的? A.x = y = z =1 B.x = (y = z + 1) C.x, y = y, x D.x += y 答案:B 2.关于Python内存管理,下列 ...
- Django框架----基础
一个小问题: 什么是根目录:就是没有路径,只有域名..url(r'^$') 补充一张关于wsgiref模块的图片 一.MTV模型 Django的MTV分别代表: Model(模型):和数据库相关的,负 ...
- Sybase 删除表的某列
Sybase 删除表的某列 Sybase 删除表的某列sql: --想删除字段temp1(该字段的所有值已置为null) alter table nh_bill_detail drop temp1;
- c++的class声明及相比java的更合理之处
或许是基于一直以来c/c++头文件声明和cXX实现物理上置于独立文件的考虑,c++中的OO在现实中基本上也是按照声明和实现分离的方式进行管理和编译,如下所示: Base.h #pragma once ...
- JAVA第十周《网络编程》学习内容总结
JAVA第十周<网络编程>学习内容总结 学习内容总结 1.初听到网络编程四个字可能会觉得很困难,实际上网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据,把数据发送到指定的位置, ...
- Java继承相关知识总结
Java继承的理解 一.概念: 一个新类从已有的类那里获得其已有的属性和方法,这种现象叫类的继承 这个新类称为子类,或派生类,已有的那个类叫做父类,或基类 继承的好处:代码得到极大的重用.形成一种类的 ...
- Git入门私房菜
昨天下午参考廖雪峰的博客和其他一些文章,简单了解了一下传说中的Git,发现常见用法入门还是挺容易上手的,在此做一些笔记,方便以后查阅和复习. Git安装 Linux sudo apt-get inst ...
- HDU 2841 Visible Trees(容斥)题解
题意:有一块(1,1)到(m,n)的地,从(0,0)看能看到几块(如果两块地到看的地方三点一线,后面的地都看不到). 思路:一开始是想不到容斥...后来发现被遮住的地都有一个特点,若(a,b)有gcd ...