题目

好秒啊,真是一道神仙的点分治

于是我们来一个暴力的\(O(nlog^2n)\)的暴力统计吧

考虑计算每一个点作为快递中心时的答案

我们考虑在这个点成为分治重心时计算这个贡献

把这个贡献分成两部分

  1. 分治块内部的点对,且不跨过分治重心,这个我们直接暴力统计就好了

  2. 分治块外部,这个又分成两种,一种是跨过分治重心的路径,显然这样的点对的贡献就是路径长度;一种是两个点都在分治块外部

都在分治块外部的话好像很难去计算了,但是我们考虑尽管对于当前的分治重心都在分治块外部,但是对于这个点在点分树上的祖先,这种点对必然在某一个祖先的分治块内部,而且是在同一棵子树里的那种

于是我们对于每一个点暴力访问其在点分树上的祖先,算一下两点之间的距离

由于只需要计算最大的贡献,我们对于每一点都只保留最大的来自于同一子树的点对贡献

但是这样还是不科学,因为我们递归进这个子树的时候,最大值也可能来自这个子树,所以我们还需要保留次大值,就是为了在处理贡献最大子树的时候不出错

显然点分树的树高是\(logn\)的,但是我们需要计算树上距离需要一个链剖求\(lca\),复杂度是\(O(nlog^2n)\)的

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=1e5+5;
const int inf=1e9;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt,w;}e[maxn<<1];
int vis[maxn],head[maxn],sum[maxn],top[maxn],son[maxn],fa[maxn],pre[maxn];
int d[maxn],Fa[maxn],h[maxn],mx[maxn],deep[maxn],col[maxn];
int S,now,rt,n,num,tmp,g,ans,m,ml;
int r[maxn<<1],len[maxn<<1];
std::vector<int> v[maxn],tp[maxn];
inline void add(int x,int y,int w) {
e[++num].v=y;e[num].nxt=head[x];
head[x]=num;e[num].w=w;
}
void getroot(int x,int fa) {
sum[x]=1,mx[x]=0;
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]||e[i].v==fa) continue;
getroot(e[i].v,x);sum[x]+=sum[e[i].v];
mx[x]=max(mx[x],sum[e[i].v]);
}
mx[x]=max(mx[x],S-sum[x]);
if(mx[x]<now) now=mx[x],rt=x;
}
void dfs1(int x) {
sum[x]=1;int maxx=-1;
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]) continue;
deep[e[i].v]=deep[x]+1;fa[e[i].v]=x;
pre[e[i].v]=pre[x]+e[i].w;
dfs1(e[i].v);sum[x]+=sum[e[i].v];
if(sum[e[i].v]>maxx) maxx=sum[e[i].v],son[x]=e[i].v;
}
}
void dfs2(int x,int topf) {
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(re int i=head[x];i;i=e[i].nxt)
if(!top[e[i].v]) dfs2(e[i].v,e[i].v);
}
inline int LCA(int x,int y) {
while(top[x]!=top[y]) {
if(deep[top[x]]<deep[top[y]]) std::swap(x,y);
x=fa[top[x]];
}
if(deep[x]<deep[y]) return x;return y;
}
inline int dis(int x,int y) {return pre[x]+pre[y]-2*pre[LCA(x,y)];}
void getro(int x,int fa,int c) {
col[x]=c;
for(re int j=0;j<v[x].size();j++) {
int t=v[x][j];
if(col[r[t^1]]==c) tmp=max(tmp,d[x]+d[r[t^1]]);
}
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]||e[i].v==fa) continue;
d[e[i].v]=d[x]+e[i].w;
getro(e[i].v,x,c);
}
}
void Dfs(int x,int fa) {
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]||e[i].v==fa) continue;
Dfs(e[i].v,x);
}
col[x]=0;
}
void dfs(int x) {
vis[x]=1;int cnt=0,m1=0,m2=0;
g=ml;d[x]=0;
for(re int i=head[x];i;i=e[i].nxt) {
if(vis[e[i].v]) continue;
col[x]=++cnt;tmp=0;d[e[i].v]=e[i].w;
getro(e[i].v,0,cnt);
tp[x].push_back(tmp);
if(tmp>m1) m2=m1,m1=tmp;
else m2=max(m2,tmp);
}
Dfs(x,0);int y=x;
while(Fa[y]) {
y=Fa[y];
int mid=2*dis(x,y)+h[y];
if(h[y]) g=max(g,mid);
}
g=max(g,m1);ans=min(ans,g);
for(re int j=0,i=head[x];i;i=e[i].nxt,j++) {
if(vis[e[i].v]) continue;
S=sum[e[i].v],now=inf,getroot(e[i].v,0);
if(tp[x][j]==m1) h[x]=m2;
else h[x]=m1;
Fa[rt]=x;dfs(rt);
}
}
int main() {
n=read(),m=read();ans=inf;
for(re int x,y,z,i=1;i<n;i++)
x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
deep[1]=1,dfs1(1),dfs2(1,1);
int tot=1;
for(re int i=1;i<=m;i++) {
r[++tot]=read();
v[r[tot]].push_back(tot);
r[++tot]=read();
v[r[tot]].push_back(tot);
len[tot]=len[tot-1]=dis(r[tot],r[tot-1]);
ml=max(ml,len[tot]);
}
S=n,now=inf,getroot(1,0);
dfs(rt);
printf("%d\n",ans);
return 0;
}

【LGP4886 】快递员的更多相关文章

  1. easyUI定区关联快递员js代码

    easyUI定区关联快递员js代码: <script type="text/javascript"> $.fn.serializeJson=function(){ va ...

  2. Luogu_4886 快递员

    Luogu_4886 快递员 一道淀粉质的题目. 先考虑最简单的算法,那便是对每个点都求一边.时间复杂度O(NM) 然后如果我们把每个点的结果对应一个高度,我们会发现.最优解是在这个对应高度形成的三维 ...

  3. Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果)

    Android动画之仿美团加载数据等待时,小人奔跑进度动画对话框(附顺丰快递员奔跑效果) 首句依然是那句老话,你懂得! finddreams :(http://blog.csdn.net/finddr ...

  4. 项目一:第七天 CRM 和bos系统实现定区关联客户,关联快递员. 通过CXF框架实现

    定区关联客户 需求:为了快递方便客户下订单(发快递),派快递员上门取件.  所以说需要让定区关联客户(知道客户属于哪个定区),定区跟快递员关系:多对多.知道让哪个快递员上门取件. 将CRM系统中,客户 ...

  5. 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据

    1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...

  6. 项目一:第三天 收派标准添加 收派标准分页查询(基于datagrid实现) 收派标准修改快递员添加 快递员列表查询

    1.收派标准添加 n jQuery easyUI window使用 n jQuery easyUI form表单校验 n 收派标准添加页面调整—url params n 服务端实现—三层 2.jQue ...

  7. 【题解】P4886快递员

    [题解]P4886 快递员 淀粉质好题!!!加深了我对点分治的理解.最近分治学了好多啊. 题目大意 给定你一颗有边权的树,再给你\(m\)和点对,请你在树上选出来一个点,使得所有点对到这个点的距离的最 ...

  8. [P4886] 快递员

    考虑在树上选个点rt作为根,并且快递中心就选这儿.计算出所有配送的代价(2*两段之和),设他们的最大值为Max.若此时存在下列情况时,可以判定Max已经为最优解. 1)存在代价为Max的配送(u,v) ...

  9. Luogu4886 快递员 点分治

    传送门 淀粉质好题啊qaq 我们先考虑随便选择一个点作为邮递中心,通过移动邮递中心找到更优的位置.将路径最大值求出,并将路径最大值对应的那一些路径拿出来考虑.可以知道,如果说这些路径中存在一条经过当前 ...

随机推荐

  1. vue setTimeout--延迟操作

    有时候我们在查询后要做某些事情,例如我查询的时候要根据某个值再去查询某些东西并和这些值一起显示的时候,我们可以对渲染数据的操作进行延迟,因为代码执行的速度是很快的而访问数据的操作相对于渲染的速度慢得多 ...

  2. Q:判断链表中是否存在环的相关问题

    问题:如何判断一个单向链表中是否存在环? 例如: 链表中存在环(B-->D): <-- <--^ | | v | A-->B-->C-->D 链表中不存在环: A- ...

  3. 【1】Singleton模式(单例模式)

    一.单例模式的介绍 说到单例模式,大家第一反应应该就是--什么是单例模式?从“单例”字面意思上理解:一个类只有一个实例.所以单例模式也就是保证一个类只有一个实例的一种实现方法罢了(设计模式其实就是帮助 ...

  4. 委托,匿名方法,lamda快速理解

    转载于用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树     这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实 ...

  5. CCScrollView的滑动体验

    最近在研究cocos2dx,由于项目中要用到内容滚动效果(内容超出容器,可以通过滑动屏幕滚动来查看),所以就毫不犹豫的选择了CCScrollView组件.   使用中发现CCScrollView的体验 ...

  6. CRM系统新思维

    客户关系管理系统(CRM系统)是管理公司当前以及未来潜在客户的系统,其主要目的是通过优化客户关系实现公司销售业绩的长期增长,它是企业信息系统的核心之一.目前,移动互联网.大数据以及人工智能技术发展日新 ...

  7. x86项目中读取注册表Register数据项的方法

    x86项目中使用Registry读取key/value的时候,会出现重定向的问题,解决方法如下: public static string GetMachineGuid() { string guid ...

  8. statistics_level 参数的应用

    转自 http://blog.csdn.net/zengmuansha/article/details/5149398 statistics_level 参数是oracle9.2开始引入的一个控制系统 ...

  9. redis介绍(1)命令介绍

    redis 的五大基本类型的简单命令 对key--value中的value的一些简单命令 keys * 查询redis中的所有key exists key 查询key是否存在 flushdb 清空当前 ...

  10. SQLServer Temp tables 数据疑问

    1. 现象 使用Cacti监控,有关于临时表的一个图形 可以看到正在使用的临时表Active Temp Tables的数量非常大,并且在非工作时间,也维持在400个左右.感觉非常奇怪,所以追查下! 2 ...