dwq推的火题啊.

这题应该不算是点分治,但是用的点分治的思想.

每次找重心,算出每一对询问的答案找到答案最大值,考虑移动答案点,使得最大值减小.

由于这些点一定不能在u的两颗不同的子树里,否则你怎么移动都不会使得答案更优.

于是答案点就只会往一棵子树里移动.

移动答案点的时候用找重心来跳保证时间复杂度.

求lca可以用树剖.

注释很详细.

// luogu-judger-enable-o2
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 100005
#define inf 1e9
using namespace std;
int n,m,rmx,size,ans,root,p;
int fa[maxn],siz[maxn],sz[maxn],top[maxn],dfn[maxn],dis[maxn];
int son[maxn],a[maxn],b[maxn],vis[maxn],dep[maxn],st[maxn];
int head[maxn],nxt[maxn<<1],to[maxn<<1],w[maxn<<1],cnt;
void add(int u,int v,int ww)
{
nxt[++cnt]=head[u];head[u]=cnt;
to[cnt]=v;w[cnt]=ww;
}
void getroot(int u,int ff)
{
sz[u]=1;int mx=0;
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(vis[v]||v==ff)continue;
getroot(v,u);sz[u]+=sz[v];
mx=max(mx,sz[v]);
}
mx=max(size-sz[u],mx);
if(mx<rmx)root=u,rmx=mx;
}
void dfs1(int u,int ff)
{
son[u]=0;fa[u]=ff;siz[u]=1;dep[u]=dep[ff]+1;
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];if(v==ff)continue;
dis[v]=dis[u]+w[i];
dfs1(v,u);siz[u]+=siz[v];
if(siz[son[u]]<siz[v])son[u]=v;
}
}
void dfs2(int u,int tf)
{
dfn[u]=++p;top[u]=tf;
if(!son[u])return;dfs2(son[u],tf);
for(int i=head[u];i;i=nxt[i])
if(to[i]!=fa[u]&&son[u]!=to[i])dfs2(to[i],to[i]);
}
int getlca(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return (dep[x]<dep[y])?x:y;
}
void solve(int u)
{
if(vis[u])return;vis[u]=1;
int mx=0,k,tot=0;
fa[u]=p=dis[u]=0;dfs1(u,0);dfs2(u,u);//树链剖分,记得初始化树剖的变量
for(int i=1;i<=m;i++)mx=max(mx,dis[a[i]]+dis[b[i]]);//找答案最大值
ans=min(ans,mx);//由于往下一个重心跳答案不一定最优,所以一路都要对答案取min
for(int i=1;i<=m;i++)//多个最大值存到数组中
if(mx==dis[a[i]]+dis[b[i]])
{
//cout<<a[i]<<" "<<b[i]<<" "<<getlca(a[i],b[i])<<endl;
if(getlca(a[i],b[i])==u)return;
//如果询问点对的两个点在不同子树,那么无论往哪个方向移动答案点,答案都不会更优
st[++tot]=dfn[a[i]];//a,b一定在一个子树内,只加入一个即可
}
for(int i=head[u],v;i;i=nxt[i])//找到第一对点询问所在的子树
if(st[1]>=dfn[v=to[i]]&&st[1]<dfn[v]+siz[v])k=v;
for(int i=2;i<=tot;i++)//如果不在同一子树,当前点就是答案,因为你不能往任意一棵子树靠近
if(st[i]<dfn[k]||st[i]>dfn[k]+siz[k]-1)return;
size=sz[k];rmx=sz[k]+1;getroot(k,0);solve(root);
}
int main()
{
cin>>n>>m;ans=inf;
for(int i=1,u,v,ww;i<n;i++)
scanf("%d%d%d",&u,&v,&ww),add(u,v,ww),add(v,u,ww);
for(int i=1;i<=m;i++)scanf("%d%d",&a[i],&b[i]);
size=n;rmx=n+1;getroot(1,0);solve(root);
printf("%d\n",ans);
return 0;
}

[luogu4886] 快递员(点分治,树链剖分,lca)的更多相关文章

  1. 树分治&树链剖分相关题目讨论

    预备知识 树分治,树链剖分   poj1741 •一棵有n个节点的树,节点之间的边有长度.方方方想知道,有多少个点对距离不超过m 题解 点分治模板题.详见我早上写的http://www.cnblogs ...

  2. CodeForces 916E Jamie and Tree(树链剖分+LCA)

    To your surprise, Jamie is the final boss! Ehehehe. Jamie has given you a tree with n vertices, numb ...

  3. NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分

    原文链接https://www.cnblogs.com/zhouzhendong/p/9275606.html 题目传送门 - 洛谷P1600 题目传送门 - LOJ#2359 题目传送门 - Vij ...

  4. 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)

    题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...

  5. POJ - 2763 Housewife Wind (树链剖分/ LCA+RMQ+树状数组)

    题意:有一棵树,每条边给定初始权值.一个人从s点出发.支持两种操作:修改一条边的权值:求从当前位置到点u的最短路径. 分析:就是在边可以修改的情况下求树上最短路.如果不带修改的话,用RMQ预处理LCA ...

  6. BZOJ 3083 遥远的国度(树链剖分+LCA)

    Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要z ...

  7. cogs 186. [USACO Oct08] 牧场旅行 树链剖分 LCA

    186. [USACO Oct08] 牧场旅行 ★★☆   输入文件:pwalk.in   输出文件:pwalk.out   逐字节对比时间限制:1 s   内存限制:128 MB n个被自然地编号为 ...

  8. 【NOIP 2015 DAY2 T3】 运输计划 (树链剖分-LCA)

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  9. Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Description 给定一棵N个节点的树,每个点 ...

随机推荐

  1. Java编程思想:压缩

    import java.io.*; import java.util.Enumeration; import java.util.zip.*; public class Test { public s ...

  2. EPPLUS 实现excel报表数据及公式填充

    年后工作第一天,根据客户要求修善EPPLUS报表. Epplus: Epplus是一个使用Open Office XML(Xlsx)文件格式,能读写Excel 2007/2010文件的开源组件 好处很 ...

  3. ISTQB TA - 边界值分析中三值测试法的注意事项

    三值测试法的定义(中文版20150601大纲): 取一个不超过边界.一个在边界上.一个超过边界的值. 这三个值其实还有另外一种叫法,分别是内点.上点和离点. 内点:不超过边界的点 上点:在边界上的点 ...

  4. Excel催化剂开源第40波-Excel插入图片做到极致的效果

    不知道是开发人员的自我要求不高还是用户的使用宽容度足够大,在众多Excel插入图片的版本中,都没有考虑到许多的可大幅度提升用户体验的细节处理. Excel催化剂虽然开发水平有限,但也在有限的能力下,尽 ...

  5. jQuery甘特图/日程图/横道图/插件

    基于JQ的一款灵活高效,支持自定义拓展的甘特图/日程图插件 支持月/周/小时等显示方式 支持拖动改变时间 展开与收起 添加/删除,刷新 节假日高亮 clicked,dblClicked,changed ...

  6. C#中使用split分割字符串的方法小结

    string s=abcdeabcdeabcde; string[] sArray=s.Split(c) ; foreach(string i in sArray) Console.WriteLine ...

  7. Ubuntu通过修改配置文件进行网络配置

    Ubuntu系统进行网络配置有的时候用图形界面不起作用,这种情况下可以直接修改某些启动脚本或配置文件 Ubuntu系统进行网络配置涉及到几个配置文件1./etc/network/interfaces ...

  8. Oculus Rift 没有声音的解决方法

    If you do not hear any audio when using Rift, please try the following steps: Check the Rift audio s ...

  9. java练习---9

    //程序员:罗元昊 2017.10.22 package cn.lyh; import com.rupeng.game.GameCore; public class L implements Runn ...

  10. mybatis动态插入数据库

    <insert id="dynamicAddUser"> insert into t_user <!-- trim 对所有的表中列名 进行动态处理 --> ...