题目链接

  总体思路……怎么说呢……是个暴力吧……

  首先用倍增预处理出每条路径的长度。  然后按长度把路径排序。

  然后二分答案。对于当前答案mid检验,怎么检验呢?

  首先差分把所有长度比mid大的链上除了LCA之外的所有点权+1。dfs求出每个点的点权,顺便记下有多少点是被所有路径经过的。对于这些点,如果有一个点使得它到他的父亲那条边被删掉后,长度最长的路径都能卡过mid,那么返回true.

  那么检查所有点发现长度最长的路径卡不过mid,那么返回false。

  然后这题搞完了。

  

#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<algorithm> using namespace std;
int n,m; inline int read(){
int num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Edge{
int next,to,dis;
}edge[];
int head[],num;
inline void add(int from,int to,int dis){
edge[++num]=(Edge){head[from],to,dis};
head[from]=num;
}
struct Node{
int from,to,dis,lca;
bool operator <(const Node &a)const{
return dis>a.dis;
}
}q[];
int s[][],d[][];
int deep[];
int vis[],e[];
int pos[],tot;
int Max,ans; void find(int x,int fa){
deep[x]=deep[fa]+;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
s[to][]=x;d[to][]=edge[i].dis;find(to,x);
}
} void dfs(int x,int fa,int size){
e[x]=vis[x];
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
dfs(to,x,size);
e[x]+=e[to];
}
if(e[x]==size) pos[++tot]=x;
} bool check(int limit){
memset(vis,,sizeof(vis));
int size=;tot=;
for(int i=;i<=m;++i){
if(q[i].dis<=limit) break;
vis[q[i].from]++;vis[q[i].to]++;vis[q[i].lca]-=;
size++;
}
dfs(,,size);
for(int i=;i<=tot;++i)
if(q[].dis-d[pos[i]][]<=limit) return ;
return ;
} int main(){
n=read(),m=read();
for(int i=;i<n;++i){
int from=read(),to=read(),dis=read();
add(from,to,dis);
add(to,from,dis);
}
for(int i=;i<=m;++i) q[i]=(Node){read(),read(),,};
find(,);
for(int j=;j<;++j)
for(int i=;i<=n;++i){
s[i][j]=s[s[i][j-]][j-];
d[i][j]=d[i][j-]+d[s[i][j-]][j-];
}
for(int i=;i<=m;++i){
int from=q[i].from,to=q[i].to; int &dis=q[i].dis,&lca=q[i].lca;
if(deep[from]<deep[to]) swap(from,to);
int f=deep[from]-deep[to];
for(int j=;(<<j)<=f;++j)
if(f&(<<j)){
dis+=d[from][j];
from=s[from][j];
}
if(from==to){
lca=from;
Max=max(Max,dis);
continue;
}
for(int j=;j>=;--j){
if(s[from][j]==s[to][j]) continue;
dis+=d[from][j]+d[to][j];
from=s[from][j];to=s[to][j];
}
dis+=d[from][]+d[to][];
lca=s[from][];
Max=max(Max,dis);
}
sort(q+,q+m+);
int l=,r=Max;
while(l<=r){
int mid=(l+r)>>;
if(check(mid)){ ans=mid;r=mid-; }
else l=mid+;
}
printf("%d",ans);
return ;
}

【Luogu】P2680运输计划(树上差分+二分)的更多相关文章

  1. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

  2. 洛谷P2680 运输计划——树上差分

    题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...

  3. NOIP2015 运输计划 (树上差分+二分答案)

    ---恢复内容开始--- 题目大意:给你一颗树,你可以把其中一条边的边权改成0,使给定的一些树链的权值和的最大值最小 把lenth定义为未修改边权时的答案 考虑二分答案,如果二分的答案成立,设修改成0 ...

  4. Luogu P2680 运输计划(二分+树上差分)

    P2680 运输计划 题意 题目背景 公元\(2044\)年,人类进入了宇宙纪元. 题目描述 公元\(2044\)年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道 ...

  5. [luogu]P2680 运输计划[二分答案][树上差分]

    [luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...

  6. luogu P2680 运输计划 (二分答案+树上差分)

    题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...

  7. luogu P2680 运输计划

    传送门 要最长链的长度最短,一秒想到二分,因为如果对于某个长度满足改掉一边的边权后能使得所有链长度不超过该长度,则所有比他长的长度也满足. 二分最终答案.我们要使得原来长度大于二分的\(mid\)的链 ...

  8. luogu P2680 运输计划 65分做法

    临近\(noip,AK\)不太现实,暴力才是王道,大佬无视 这里只介绍\(65\)分做法 ① \(m==1\) 的情况 很明显 就一条路径,当然要贪心选着一条路径路上的最大的边喽 傻逼分\(get 2 ...

  9. 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)

    P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...

  10. P2680 运输计划(二分+树上差分)

    P2680 运输计划 链接 分析: 二分+树上差分. 首先可以二分一个答案,那么所有比这个答案大的路径,都需要减去些东西才可以满足这个答案. 那么减去的这条边一定在所有的路径的交集上. 那么如果求快速 ...

随机推荐

  1. Android程序中使用iconfont心得

    1.关于iconfont iconfont既是icon又是font,具体来说应该是用font形式展现的icon.与传统图片格式的图标不同,这一种图标因为是以字体形式展现的,所以更改大小.颜色.背景颜色 ...

  2. jdbc接口的一种类比——打酱油

    jdbc很简单,这里只是为了方便自己的记忆.模型也许有缺陷,但本质是相同的. jdbc可以屏蔽数据库的底层的不同,让我们有能力用java语言统一访问不同的数据库.就像打酱油一样,可以去超市买,也可以去 ...

  3. 电脑连接海信电视 HDMI

    注意:我们家的电视是海信的,所以不能代表所有的电视哦~~~ 家里电视有线电视已经过期很长时间了,早就想把电脑连接到电视上用电视做显示器的心了,今天来兴趣了,就弄了一下!!! 用电脑连接电视需要先解决两 ...

  4. 洛谷 P1744 采购特价商品

    题目背景 <爱与愁的故事第三弹·shopping>第一章. 题目描述 中山路店山店海,成了购物狂爱与愁大神的“不归之路”.中山路上有n(n<=100)家店,每家店的坐标均在-1000 ...

  5. make 与makefile(会不会写 makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。)

    跟我一起写 Makefile /**/ 陈皓 (CSDN) 概述 —— 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉 ...

  6. js 前端不调接口直接下载图片

    // 下载图片 downPhoto (path) { this.downloadFiles(path) }, // 下载 downloadFiles (content) { console.log(c ...

  7. 安装vc++6.0的步骤

    我们学习计算机,就必须要先将编程的c语言学好,打好基础,学习c语言最好的方法就是多上机联系,对于联系我们需要在自己的电脑上安装vc++6.0来进行平日里的联系.1.打开电脑进行联网,打开浏览器搜索vc ...

  8. shell脚本,按字母出现频率降序排序。

    [root@localhost oldboy]# cat file the squid project provides a number of resources toassist users de ...

  9. js函数式编程(三)-compose和pointFree

    compose即函数嵌套组合 组合compose在第一篇已经初见端倪,可以感受一下.compose函数的实现用闭包的方法.不完善实现如下: const compose = (f, g) => { ...

  10. 初涉树形dp

    算是一个……复习以及进阶? 什么是树形dp 树形dp是一种奇妙的dp…… 它的一个重要拓展是和各种树形的数据结构结合,比如说在trie上.自动机上的dp. 而且有些时候还可以拓展到环加外向树.仙人掌上 ...