看到题意最小化最长路径,显然二分答案,枚举链长度不超过$\text{mid}$,然后尝试检验。`````

检验是否存在这样一个边置为0后,全部链长$\le\text{mid}$,其最终目标就是、要让所有$>\text{mid}$的链长通过找出一个为0的公共边减掉而全部变为$\le\text{mid}$的。

那么,统计出这$tot$条超出$\text{mid}$的链的路径上覆盖的边,一条被覆盖了$tot$次的边就可能具备条件,于是贪心找最大的满足条件的边,看是否可以把所有链(也就是最长链)搞成$\le\text{mid}$的,$O(n)$树上差分即可。

于是$O(n\text{log}len)$。

准备去(gu)学(gu)习(gu)的做法:据说当年考场这题log是被卡掉一两个点的?所以有线性做法?待补

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=3e5+;
struct thxorz{int to,nxt,w;}G[N<<];
struct stothx{int to,nxt,id;}Q[N<<];
struct query{int x,y,lca,dis;}q[N];
int Head[N],tot=,qh[N],qt;
int n,m,L,R,maxdis,maxe;
inline void Addedge(int x,int y,int z){
G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;
G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot,G[tot].w=z;
}
inline void AddQuery(int x,int y,int id){
Q[++qt].to=y,Q[qt].nxt=qh[x],qh[x]=qt,Q[qt].id=id;
Q[++qt].to=x,Q[qt].nxt=qh[y],qh[y]=qt,Q[qt].id=id;
}
#define y G[j].to
#define qy Q[j].to
int vis[N],anc[N],dep[N];
int get_anc(int x){return x==anc[x]?x:anc[x]=get_anc(anc[x]);}
void tarjan(int x,int fa){
anc[x]=x;
for(register int j=Head[x];j;j=G[j].nxt)if(y^fa)dep[y]=dep[x]+G[j].w,tarjan(y,x),anc[y]=x;
vis[x]=;
for(register int j=qh[x];j;j=Q[j].nxt)if(vis[qy])
q[Q[j].id].lca=get_anc(qy),q[Q[j].id].dis=dep[x]+dep[qy]-(dep[q[Q[j].id].lca]<<),MAX(R,q[Q[j].id].dis);
}
int d[N],del,cnt;
int dfs(int x,int c){
int ret=d[x];
for(register int j=Head[x];j;j=G[j].nxt)if(y^G[c^].to)ret+=dfs(y,j);
if(ret==cnt)MAX(del,G[c].w);
return ret;
}
#undef y
#undef qy
inline int check(int mid){
memset(d,,sizeof d),del=cnt=;
for(register int i=;i<=m;++i)if(q[i].dis>mid)++d[q[i].x],++d[q[i].y],d[q[i].lca]-=,++cnt;
dfs(,);
return maxdis-del<=mid;
}
int main(){//freopen("test.in","r",stdin);freopen("test.ans","w",stdout);
read(n),read(m);
for(register int i=,x,y,z;i<n;++i)read(x),read(y),read(z),Addedge(x,y,z),MAX(L,z);
for(register int i=;i<=m;++i)read(q[i].x),read(q[i].y),AddQuery(q[i].x,q[i].y,i);
tarjan(,);maxdis=R,maxe=L;L=R-L;//dbg(maxdis),dbg(maxe);
while(L<R){
int mid=L+R>>;
if(check(mid))R=mid;
else L=mid+;
}
printf("%d\n",L);
return ;
}

总结反思:瓶颈在check。关键在于要放眼全部,不要都放在maxdis上;求边若干次覆盖的统计可以往树上差分上想。

loj2425 「NOIP2015」运输计划[二分答案+树上差分]的更多相关文章

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

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

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

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

  3. 「NOIP2015」运输计划

    传送门 Luogu 解题思路 首先这题可以直接二分答案,然后我们每次都把属于长度大于二分值的路径上的边标记一次,表示选这条边可以优化几条路径. 然后我们显然是要选一条覆盖次数等于需要覆盖的路径数并且长 ...

  4. BZOJ 4326: NOIP2015 运输计划(二分,树上差分)

    Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1945  Solved: 1243[Submit][Status][Discuss] Descript ...

  5. P2680 运输计划[二分+LCA+树上差分]

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

  6. 【bzoj4326】[NOIP2015]运输计划 二分答案+LCA

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

  7. luogu2680 [NOIp2015]运输计划 (tarjanLca+二分答案+树上差分)

    我们先不会就二分一下答案,设它是x,我们要判断它能不能满足 为了满足这个答案,我们就要让原本路径长度大于x的所有路径都经过某条边,而且这条边还要大于等于最长的路径-x 于是运用树上差分的思想,对于所有 ...

  8. BZOJ 4326 NOIP2015 运输计划(二分答案 + 树上差分思想)

    题目链接  BZOJ4326 这个程序在洛谷上TLE了……惨遭卡常 在NOIP赛场上估计只能拿到95分吧= = 把边权转化成点权 首先求出每一条路径的长度 考虑二分答案,$check(now)$ 对于 ...

  9. 洛谷P2680 运输计划 [LCA,树上差分,二分答案]

    题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...

随机推荐

  1. springboot整合es客户端操作elasticsearch(三)

    继续上个随笔: 那么我们只需要修改controller中文件就可以完成相关操作 本次主要是对文档得操作: 更新文档: package com.cxy.elasticsearch.controller; ...

  2. luoguP2634聪聪可可(点分治)

    题目链接:https://www.luogu.org/problem/P2634 题意:给一颗树,求距离的模3为0的点对数量,注意(1,1)算一个点对,(1,2)和(2,1)算两个点对. 思路:和点分 ...

  3. 阿里云服务器安装svn完整步骤,避免新手可能出现的所有错误

    centos6.8,没有安装svn的情况: 1.安装: yum install subversion (这一步一般不会错) 2.创建svn版本库: cd /root mkdir -p svn/proj ...

  4. 剑指offer6:旋转数组的最小数字

    1. 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一 ...

  5. luogu P3959(2017noipTG D2T2

    luogu P3959(2017noipTG D2T2 不知道为什么,这两天见了好多伪装成图的dp题,这道也是. 最短路只有40分,实际上可以从数据范围n<=12看出来是状压dp. soluti ...

  6. linux下安装anconda3

    Liunx下安装anconda3其实特变简单,只需这几步骤 1.  首先要到网上下载一个ancoda3的安装包.然后在上传到linux上面即可 3. 是不是特别简单呢?哈哈

  7. QT目录模型QDirModel的使用(一个model同时连接tree,list,table)

    3#include <QApplication>#include <QAbstractItemModel>#include <QAbstractItemView># ...

  8. Python 最常见的 170 道面试题解析:2019 最新

    Python 最常见的 170 道面试题解析:2019 最新 2019年06月03日 23:30:10 GitChat的博客 阅读数 21329 文章标签: PythonPython入门Python面 ...

  9. Scala学习六——对象

    一.本章要点 用对象作为但例或存放工具的方法 类可以拥有一个同名的伴生对象 对象可以扩展类或特质 对象的apply方法通常用来构造伴生类的新实例 如果不想显示定义main方法,可以扩展App特质的对象 ...

  10. c#中异常捕获,回滚

    语法: try { 有可能出现错误的代码写在这里 } catch { 出错后的处理 } 如果try中的代码没有出错,则程序正常运行try中的内容后,不会执行catch中的内容, 如果try中的代码一但 ...