题目大意:一个$n$个点的树,树上有$m$个点对$(a,b)$,找到一个点$x$,使得$max(dis(x,a_i)+dis(x,b_i))$最小

如果做过幻想乡的战略游戏这道题,应该这道题的思路一眼能看出来

首先如果从一个点向能使答案变小的子树上走,那么从子树上一定不会再回到这个点

所以考虑一个暴力,即每次计算所有子树的答案,然后向最优的方向走

这显然是正确的,但是不够优秀

我们再深入分析一下这道题,可以发现,当且仅当所有的距离等于最大值的点对都在它的一个子树内时才可能使得答案变优

很好理解,因为如果不在通一个子树内,不论向任何地方走,总会有点对的最大值变得更大

然后这样我们就可以用点分治的$getroot$来优化这个过程,复杂度为$nlogn$

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define M 100010
using namespace std;
int n,m,num,rt,S,ans=1e9;
int head[M],size[M],maxn[M],bel[M],dis[M],u[M],v[M],st[M];
bool vis[M];
struct point{int to,next,dis;}e[M<<];
void add(int from,int to,int dis)
{
e[++num].next=head[from];
e[num].to=to;
e[num].dis=dis;
head[from]=num;
}
void getroot(int x,int fa)
{
size[x]=maxn[x]=;
for(int i=head[x];i;i=e[i].next)
{
int to=e[i].to;
if(to==fa||vis[to]) continue;
getroot(to,x),size[x]+=size[to];
maxn[x]=max(maxn[x],size[to]);
}
maxn[x]=max(maxn[x],S-size[x]);
if(maxn[x]<maxn[rt]) rt=x;
} void dfs(int x,int fa,int id)
{
bel[x]=id;
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=fa)
{
dis[e[i].to]=dis[x]+e[i].dis;
dfs(e[i].to,x,id);
}
} void solve(int x)
{
if(vis[x]) {printf("%d\n",ans);exit();}
vis[x]=true,dis[x]=;
for(int i=head[x];i;i=e[i].next)
{
dis[e[i].to]=e[i].dis;
dfs(e[i].to,x,e[i].to);
}
int MX=,top=,pos=;
for(int i=;i<=m;i++)
{
if(dis[u[i]]+dis[v[i]]>MX)
{
MX=dis[u[i]]+dis[v[i]];
st[top=]=i;
}
else if(dis[u[i]]+dis[v[i]]==MX)
st[++top]=i;
}
ans=min(ans,MX);
for(int i=;i<=top;i++)
{
if(bel[u[st[i]]]!=bel[v[st[i]]])
{
printf("%d\n",ans);
exit();
}
else
{
if(!pos) pos=bel[u[st[i]]];
else if(pos!=bel[u[st[i]]])
{
printf("%d\n",ans);
exit();
}
}
}
S=size[pos],rt=;
getroot(pos,),solve(rt);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
int a,b,c;scanf("%d%d%d",&a,&b,&c);
add(a,b,c),add(b,a,c);
}
for(int i=;i<=m;i++) scanf("%d%d",&u[i],&v[i]);
S=maxn[]=n,getroot(,),solve(rt);
return ;
}

[洛谷P4886]快递员的更多相关文章

  1. 【洛谷 P4886】 快递员 (点分治)

    这题因为一些小细节还是\(debug\)了很久...不过我第一次用脚本对拍,不亏. 先随便找一个点作为根,算出答案,即所有点对到这个点的距离和的最大值,并记录所有距离最大的点对.如果这个点在任意一个距 ...

  2. 【LGR-051】洛谷9月月赛

    [LGR-051]洛谷9月月赛 luogu 签到题 description 给出\(K\)和质数\(m\),求最小的\(N\)使得\(111....1\)(\(N\)个\(1\))\(\equiv k ...

  3. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  4. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  5. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  6. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  7. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  8. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  9. 洛谷P1538迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

随机推荐

  1. Hibernate的调用数据库的存储过程

    Hibernate并没有给出直接调用数据库的存储过程的API,所以咋们就要通过调用原生的的connection对象来实现对存储过程的条用 Hibernate调用存储过程的步骤: 1:获得原生conne ...

  2. Codeforces Round #425 (Div. 2))——A题&&B题&&D题

    A. Sasha and Sticks 题目链接:http://codeforces.com/contest/832/problem/A 题目意思:n个棍,双方每次取k个,取得多次数的人获胜,Sash ...

  3. 如何做rom,体验做rom过程,附图文教程,感谢各位romer

    http://bbs.gfan.com/android-5408130-1-1.html 有人问我,我简单的写一下,来源XDA,运行环境ubuntu 10.4. ubuntu安装很简单,在window ...

  4. 转!!Linux 里的 2>&1 究竟是什么

    原博文地址:https://blog.csdn.net/shunzi1046/article/details/76110963 我们在Linux下经常会碰到nohup command>/dev/ ...

  5. 七个可以提升python程序性能的好习惯,你知道吗?

    掌握一些技巧,可尽量提高Python程序性能,也可以避免不必要的资源浪费.今天就为大家带来七个可以提升python程序性能的好习惯,赶快来学习吧:. 1.使用局部变量 尽量使用局部变量代替全局变量:便 ...

  6. sql之密码保存

    HashBytes (Transact-SQL) 其他版本   返回其输入的 MD2.MD4.MD5.SHA 或 SHA1 哈希值.  Transact-SQL 语法约定 语法         Has ...

  7. Java集合—Queue(转载)

    Queue用于模拟队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器.新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素.通常,队列不允许随机访问队列中的元素 ...

  8. POJ1459:Power Network(dinic)

    题目链接:http://poj.org/problem?id=1459 题意:有n个结点,np个发电站,nc个消费者,m个电力运输线.接下去是m条边的信息(u,v)cost,cost表示边(u,v)的 ...

  9. matplotlib绘制等高线图

    参考自Matplotlib Python 画图教程 (莫烦Python)(12)_演讲•公开课_科技_bilibili_哔哩哔哩 https://www.bilibili.com/video/av16 ...

  10. 转: MYSQL获取更新行的主键ID

    在某些情况下我们需要向数据表中更新一条记录的状态,然后再把它取出来,但这时如果你在更新前并没有一个确认惟一记录的主键就没有办法知道哪条记录被更新了. 举例说明下: 有一个发放新手卡的程序,设计数据库时 ...