Luogu_4886 快递员

一道淀粉质的题目。

先考虑最简单的算法,那便是对每个点都求一边。时间复杂度O(NM)

然后如果我们把每个点的结果对应一个高度,我们会发现。最优解是在这个对应高度形成的三维图像中的谷底(谷缝)

也就数说,对于一条链来说,他是一个开口向上的类似二次函数的一个图形。

具有类似单调性的一类性质。

在O(NM)的算法中,可以使用其剪枝。既是如果相邻的节点的答案要大于当前节点,那么我们就不向那个节点进行搜索。

为什么? 如果相邻节点的答案小于当前点,那么说明,当前的最长链的两端都在相邻节点所确定的子树中。

所以我们往这颗子树中走就用可能是更优的。(随时取min)

为什么说是可能?因为这个最长链的位置可能改动。


对于这个二次函数图像,我们可以使用一个类似二分的方法,在log时间复杂度中找到最小值。

就是前文说的类似单调性一样的东西。

所以我们可以利用最长连所在的子树的重心进行检验。

因为重心的性质,我们就可以每次将问题至少缩小一半规模。

至于什么时候退出呢?

要么递归到底,要么子树重心的答案大于当前最优答案。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring> using std::min;
using std::max; const int maxn=101000;
const int inf=0x7fffffff; struct node
{
int p;
int value;
int nxt;
}; node line[maxn<<1];
int head[maxn],tail;
int query[maxn][2];
int vis[maxn],dis[maxn],size[maxn],f[maxn];
int belong[maxn];
int n,m,root,sum;
int ans,where; int read()
{
char c=getchar();
int res=0;
while(c>'9'||c<'0') c=getchar();
while(c>='0'&&c<='9')
{
res=(res<<1)+(res<<3)+c-'0';
c=getchar();
}
return res;
} void add(int a,int b,int c)
{
line[++tail].p=b;
line[tail].value=c;
line[tail].nxt=head[a];
head[a]=tail;
return ;
} void get_dis(int now,int fa,int Dis,int Belong)
{
dis[now]=Dis;
belong[now]=Belong;
for(int i=head[now];i;i=line[i].nxt)
{
int v=line[i].p;
if(v==fa) continue;
get_dis(v,now,Dis+line[i].value,Belong);
}
return ;
} void get_size(int now,int fa)
{
size[now]=1;
for(int i=head[now];i;i=line[i].nxt)
{
int v=line[i].p;
if(vis[v]||v==fa) continue;
get_size(v,now);
size[now]+=size[v];
}
return ;
} void get_hry(int now,int fa)
{
size[now]=1;f[now]=0;
for(int i=head[now];i;i=line[i].nxt)
{
int v=line[i].p;
if(vis[v]||v==fa) continue;
get_hry(v,now);
size[now]+=size[v];
f[now]=max(f[now],size[v]);
}
f[now]=max(f[now],sum-size[now]);
if(f[now]<f[root]) root=now;
return ;
} void solve(int now)
{
sum=size[now];
root=0;
get_hry(now,0);
int Max=0,Be=0,cnt=0;
vis[root]=1;get_size(root,0);
belong[root]=dis[root]=0;
for(int i=head[root];i;i=line[i].nxt)
get_dis(line[i].p,root,line[i].value,++cnt);
for(int i=1;i<=m;i++)
Max=max(Max,dis[query[i][0]]+dis[query[i][1]]);
ans=min(ans,Max);
// if(ans>Max)
// {
// ans=Max;
// where=root;
// }
for(int i=1;i<=m;i++)
{
int A=query[i][0],B=query[i][1];
if(dis[A]+dis[B]!=Max) continue;
if(belong[A]==belong[B]&&(!Be||Be==belong[A]))
Be=belong[A];
else if((!belong[A]||!belong[B])&&(!Be||Be==belong[A]+belong[B]))
Be=belong[A]+belong[B];
else return ;
}
for(int i=head[root];i;i=line[i].nxt)
if(!vis[line[i].p]&&Be==belong[line[i].p])
{
solve(line[i].p);
return ;
}
return ;
} int main()
{
n=read();m=read();
for(int i=1,a,b,c;i<n;i++)
{
a=read();b=read();c=read();
add(a,b,c);
add(b,a,c);
}
for(int i=1;i<=m;i++)
query[i][0]=read(),query[i][1]=read();
f[0]=inf;size[1]=n;ans=inf;
solve(1);
printf("%d",ans);
//printf("\n%d",where);
}

Luogu_4886 快递员的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 【题解】P4886快递员

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

  7. [P4886] 快递员

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

  8. Luogu4886 快递员 点分治

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

  9. 【LGP4886 】快递员

    题目 好秒啊,真是一道神仙的点分治 于是我们来一个暴力的\(O(nlog^2n)\)的暴力统计吧 考虑计算每一个点作为快递中心时的答案 我们考虑在这个点成为分治重心时计算这个贡献 把这个贡献分成两部分 ...

随机推荐

  1. python 实现websocket

    python中websocket需要我们自己实现握手代码,流程是这样:服务端启动websocket服务,并监听.当客户端连接过来时,(需要我们自己实现)服务端就接收客户端的请求数据,拿到请求头,根据请 ...

  2. SQLServer数据库系统概念

    数据模型是一种抽象模型,现实世界中的客观事物是彼此相互联系的 (1)数据模型是一组集成的概念,用户描述和操作组织内的数据,数据间的联系以及对数据的约束,它包含了数据结构,数据操作和完整性约束 (2)概 ...

  3. Date()函数的用法

  4. laravel开发之-php artisan命令

    php artisan :所有的命令列表 php artisan make:controller 文件夹名称/控制器名称 :创建控制器的命令以及控制器放置的文件夹 php artisan make:m ...

  5. laravel之引入图片上传类

    1.在官网http://www.uploadify.com/ 下载插件,flash verison 的版本是免费版 2.解压后将文件夹放置在指定的目录下 3.前端导入css,js文件,可以仿照文件夹中 ...

  6. 利用Ogr将Kml转为Shape【1】

    最近在研究Kml怎么转化为Shape文件,因为客户中很多在原来采集了一部分数据都是在google Earth中,而我们的应用中特别需要这份数据,所以打算先在GE中把这份数据导出为Kml或Kmz文件,然 ...

  7. 推荐js库: underscore

    Underscore封装了常用的JavaScript对象操作方法,用于提高开发效率. 之间没用他之前,自己写,那是相当的酸爽. 如循环处理: for(var i=0;i<data.length; ...

  8. 新年开篇-ERP和OA集成步骤

    1.备份要升级帐套的数据库 6点 - 6点10分完成 重启 服务器 2.升级数据库 6点30 - 7点 3.配置ERP电子表单和EasyFlow表单 7点 - 7点30分 录入多公司信息(电子签核), ...

  9. python字典的排序

    # -*- coding:UTF-8 -*- def dict_sort(): # 按照value的值从大到小的顺序进行排序 dic = {'a': 31, 'bc': 5, 'c': 3, 'asd ...

  10. Android开发(7)数据库和Content Provider

    问题聚焦: 思想:应用程序数据的共享 对数据库的访问仅限于创建它的应用程序,但是事情不是绝对的 Content Provider提供了一个标准的接口,可供其他应用程序访问和使用其他程序的数据 下面我们 ...