传送门

十分显然完成工作的时间和航耗时最长的运输计划有关

所以题目意思就是要求最大值最小

所以可以想到二分

把所有大于mid时间的航线打上标记,显然删边只能在所有这些航线的公共路径上

要如何快速打标记是个问题

二分已经有一个log,所以只能承受O(n)的判断

如果能知道一条边的经过次数,那么就知道这条边是否在公共路径上

容易想到树上差分,预处理一波 lca 后复杂度可行

删边肯定贪心地删能删的最长边

要如何判断删边后是否最长路径小于mid呢

显然可以预处理出不删前的最长路径

如果最长路径减去删的边 ≤ mid 那么其他路径减删去的边肯定不大于mid(注意删去的边在所有原长超过mid的路径上)

至于其他原长小于 mid 的路径根本不用考虑

所以总结一下就是二分+树上差分

luogu第13个点真是用sang心xin良bing苦kuang,把复杂度卡满了

求LCA可能用树剖会快一点,然而懒得写...

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
inline int read()
{register int x=0,f=1; char ch=getchar();while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }return x*f;
}
const int N=3e5+7;
int fir[N],from[N<<1],to[N<<1],val[N<<1],cntt;
inline void add(int &a,int &b,int &c)
{from[++cntt]=fir[a];fir[a]=cntt; to[cntt]=b; val[cntt]=c;
}int f[N][21],dep[N],dis[N],frm[N];//f和dep用来求LCA,dis是点到根的距离,用来求最长路径,frm是连接父节点的边的编号
void dfs1(int &x,int &fa)//第一遍dfs处理f,dep,dis,frm
{f[x][0]=fa; dep[x]=dep[fa]+1;for(int i=1;i<=19;i++) f[x][i]=f[f[x][i-1]][i-1];for(int i=fir[x];i;i=from[i]){int &v=to[i]; if(v==fa) continue;dis[v]=dis[x]+val[i]; frm[v]=i; dfs1(v,x);}
}
inline int LCA(int x,int y)//求LCA
{if(dep[x]<dep[y]) swap(x,y);for(int i=19;i>=0;i--)if(dep[f[x][i]]>=dep[y]) x=f[x][i];if(x==y) return x;for(int i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];return f[x][0];
}int n,m,cnt[N],lca[N],sum[N],tot,mxlen,rt=1;
//cnt是差分数组,lca顾名思义,sum[i]是第i条路径的长度,tot记录有几条边原长大于mid,mxlen是最长路径长度,rt是根节点
struct data
{int a,b;
}d[N];//存运输计划
int pos;//记录最长边的编号
void dfs2(int &x)//dfs2处理每条边经过次数
{for(int i=fir[x];i;i=from[i]){int &v=to[i]; if(v==f[x][0]) continue;dfs2(v); cnt[x]+=cnt[v];}if(cnt[x]==tot&&val[frm[x]]>val[pos]) pos=frm[x];//如果当前节点被所有大于mid的边经过则考虑更新pos
}
inline bool pd(int &p)//判断合法性,p就是mid
{tot=pos=0; memset(cnt,0,sizeof(cnt));//初始化for(register int i=1;i<=m;i++){if(sum[i]<=p) continue;cnt[d[i].a]++; cnt[d[i].b]++;cnt[lca[i]]-=2;tot++;//记录差分
    }dfs2(rt);return mxlen-val[pos]>p ? 0 : 1;//判断
}int main()
{int a,b,c;n=read(); m=read();for(register int i=1;i<n;i++){a=read(),b=read(),c=read();add(a,b,c); add(b,a,c);}dfs1(rt,rt);for(register int i=1;i<=m;i++){d[i].a=read(); d[i].b=read();lca[i]=LCA(d[i].a,d[i].b);//预处理lcasum[i]=dis[d[i].a]+dis[d[i].b]-(dis[lca[i]]<<1);//求出summxlen=max(mxlen,sum[i]);//尝试更新maxlen
    }register int l=0,r=mxlen,mid;while(l<=r){mid=l+r>>1;pd(mid) ? r=mid-1 : l=mid+1;}printf("%d",l);return 0;
}

转载于:https://www.cnblogs.com/LLTYYC/p/9828248.html

P2680 运输计划相关推荐

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

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

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

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

  3. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  4. 洛谷P2680:运输计划(倍增、二分、树上差分)

    传送门 文章目录 题目描述 解析 问题 代码 题目描述 解析 求最大值的最小值 容易想到二分 然后...就没有然后了... 看了题解 学会了一个新技能:树上差分 (其实学长之前好像讲过...) 一般的 ...

  5. [NOIP2015提高组]运输计划

    题目:BZOJ4326.洛谷P2680.Vijos P1983.UOJ#150.codevs4632.codevs5440. 题目大意:有一棵带权树,有一些运输计划,第i个运输计划从ai到bi,耗时为 ...

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

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

  7. BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 1388  Solved: 860 [Submit][Stat ...

  8. cogs2109 [NOIP2015] 运输计划

    cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...

  9. UOJ #150 【NOIP2015】 运输计划

    题目描述 公元 \(2044\) 年,人类进入了宇宙纪元. \(L\) 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个星球之间,这 \(n-1\) 条航道连通了 \(L ...

最新文章

  1. mysql怎么判断2个时间戳为同一天_请教一个需求js怎么判断时间戳是否属于同一天...
  2. android子线程没有运行完,android假如主线程依赖子线程A的执行结果,如何让A执行完成,之后主线程再往下执行呢?...
  3. 别忽视新冠轻症,它会损害你的记忆力
  4. IntelliJ IDEA 17和Maven构建javaWeb项目
  5. [loj6391][THUPC2018]淘米神的树(Tommy)
  6. APP自动化测试系列之adb连接真机和模拟器
  7. 51nod 1275 连续子段的差异(twopointer+单调队列)
  8. 自定义初学5——自定义View显示图片
  9. 骨架屏 (Skeleton Screen)
  10. 【Prison Break】第三天(3.29)
  11. 在CentOS6.5上安装/启动PostgreSQL
  12. vivox6Android版本,vivo x6有几个版本?vivo x6各版本区别对比评测
  13. 智能烟感与物联网卡可以了解一波
  14. wps一直显示正在备份怎么办_wps怎么解除自动备份
  15. 依然仰望星空,脚踏实地——个人CSDN年度总结。
  16. 去掉CAJViewer广告的方法
  17. 希尔贝壳参展世界人工智能大会 | WAIC 2021
  18. 【HDU】1535 Invitation Cards 最短路
  19. 用shell手撸容器实现批量用openssl签证书
  20. 终于解决了不能打开网页,但是可以聊天的问题。。。

热门文章

  1. rstudio 导出结果_RStudio如何完美导出包含中文的图
  2. 关于mysql修改密码 set password for root@localhost = password(‘xxx‘);报错解决方法
  3. 前端工具:推荐几款UI设计师好用的设计软件
  4. 网络知识:交换机中的半双工与全双工知识笔记
  5. [收集]Sublime Text 3常用快捷键
  6. vue全局引入openlayers_vue中使用OpenLayers(一):引入谷歌地图
  7. python3列表_Python3 列表List(十一)
  8. php位运算重要吗,PHP位运算的用途
  9. python【进阶】4.文本和字节序列
  10. 新的一年,碎片化学习前端,我推荐这几个公众号~