P2680-运输计划【LCA,树上差分,二分答案】
正题
题目链接:https://www.luogu.org/problemnew/show/P2680
题目大意
一棵带权无根树,给出若干条路径。选择一条边使其边权变为0,要求路径的长度的最大值最小。
解题思路
首先最大值最小我们可以想到二分答案,现在我们二分到midmidmid了,我们如何判断是否满足。
我们我们发现只需要管路径长度大于midmidmid的,假设有numnumnum条,那么我们必须找到一条边满足:
- 这numnumnum条路径都经过这个点
- 若这个点的边权为www,那么要求满足最长的路径长度maxlen−w≤midmaxlen-w\leq midmaxlen−w≤mid
首先我们用LCALCALCA可以计算出每条路径的原始长度,然后我们可以用树上差分有多少条路径经过一个点。
时间复杂度O(nlogn)O(n\log n)O(nlogn)
OverOverOver
codecodecode
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int N=300100;
struct edge_node{int to,next,w;
}a[N*2];
int n,m,tot,t,num,del,maxs;
int ls[N],dep[N],dis[N],f[N][30];
int lca[N],dx[N],dy[N],len[N],acr[N];
queue<int> q;
void addl(int x,int y,int w)
{a[++tot].to=y;a[tot].next=ls[x];a[tot].w=w;ls[x]=tot;
}
void bfs()
{t=(int)(log(n)/log(2))+1;q.push(1);dep[1]=1;while(!q.empty()){int x=q.front();q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(dep[y]) continue;dep[y]=dep[x]+1;f[y][0]=x;dis[y]=dis[x]+a[i].w;q.push(y);}}for(int i=1;i<=t;i++)for(int j=1;j<=n;j++)f[j][i]=f[f[j][i-1]][i-1];
}
int LCA(int x,int y)
{if(dep[x]>dep[y]) swap(x,y);for(int i=t;i>=0;i--)if(dep[f[y][i]]>=dep[x])y=f[y][i];if(x==y) return x;for(int i=t;i>=0;i--)if(f[y][i]!=f[x][i])y=f[y][i],x=f[x][i];return f[x][0];
}
void dfs(int x,int fa,int rec)
{for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa) continue;dfs(y,x,i);acr[x]+=acr[y]; }if(acr[x]==num)del=max(del,a[rec].w);
}
int main()
{freopen("testdata.in","r",stdin);scanf("%d%d",&n,&m);for(int i=1;i<n;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);addl(x,y,w);addl(y,x,w);}bfs();int l=0,r=N*1000;for(int i=1;i<=m;i++){scanf("%d%d",&dx[i],&dy[i]);lca[i]=LCA(dx[i],dy[i]);len[i]=dis[dx[i]]+dis[dy[i]]-dis[lca[i]]*2;maxs=max(maxs,len[i]);}while(l<=r){int mid=(l+r)/2;memset(acr,0,sizeof(acr));num=0;del=0;for(int i=1;i<=m;i++)if(len[i]>mid)acr[dx[i]]++,acr[dy[i]]++,acr[lca[i]]-=2,num++;dfs(1,1,0);if(maxs-del<=mid) r=mid-1;else l=mid+1;}printf("%d",l);
}
P2680-运输计划【LCA,树上差分,二分答案】相关推荐
- 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)
[题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...
- P2680 运输计划(树上差分+lca+二分)
题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...
- BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Submit: 1388 Solved: 860 [Submit][Stat ...
- [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告
[NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...
- 洛谷P2680:运输计划(倍增、二分、树上差分)
传送门 文章目录 题目描述 解析 问题 代码 题目描述 解析 求最大值的最小值 容易想到二分 然后...就没有然后了... 看了题解 学会了一个新技能:树上差分 (其实学长之前好像讲过...) 一般的 ...
- luogu P2680 运输计划 (二分答案+树上差分)
题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...
- [luogu2680] 运输计划 (lca+二分+树上差分)
传送门 Description Input Output 一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间. Sample Input 6 3 1 2 3 1 6 4 3 1 7 4 3 ...
- 【codevs4632】【BZOJ4326】运输计划,链剖+二分+差分
传送门1 传送门2 写在前面: 当初洗澡的时候脑补了下这个题,觉得很简单直到看到题面,才发现自己记错了,自此开始不归路 思路:这里的链剖实际上就是求每个操作的路径长度(也可以LCA求),然后我想到了二 ...
- P2680 运输计划
传送门 十分显然完成工作的时间和航耗时最长的运输计划有关 所以题目意思就是要求最大值最小 所以可以想到二分 把所有大于mid时间的航线打上标记,显然删边只能在所有这些航线的公共路径上 要如何快速打标记 ...
最新文章
- React模式:集中式PropTypes
- 数据科学研究院第四届“院长接待日”成功举办
- Java多线程2:Thread中的实例方法
- Python的time库的一些简单函数以及用法
- nifty ui_Nifty JUnit:在方法和类级别上使用规则
- virtualbox下安装archlinux
- win7电脑更改不了分辨率的解决方法
- Linux怎么添加交换空间,如何在Ubuntu上增加swap交换空间
- linux 用户管理和帮助命令
- mysql中删除数据库中的表格数据恢复_恢复从数据库中删除的表
- 换了一种管用pip安装方法,还有管用的python版hdf5(包名为h5py)安装方法
- ubuntu命令查询版本和内核版本
- JDK8新特性(一)之Lambda表达式
- SpringMVC访问流程
- 宝塔Inode信息使用率100%满了怎么清理?
- 尔雅 科学通史(吴国盛) 个人笔记及课后习题 2018 第七章 实验传统的兴起
- 小程序12306服务器,微信小程序12306来了!史上最详细体验出炉!
- Word编号设置和跳到尾页快捷键
- 旋转正方体加径向渐变
- 京剧《赤壁》舌战群儒
热门文章
- apache weblogic ssl linux,apache基于ssl配置weblogic(完结篇)
- html语言可以写模版继承吗,Django框架(十一):模板介绍、模板语言、模板继承、HTML转义...
- python 局部变量 占内存吗_Python中全局变量和局部变量的理解与区别
- fb静态区域_fb 静态数据
- activity 防止多次打开_Android开发Activity任务和返回栈
- 7-1 字母统计图 (10 分)(思路+详解)
- C++,Java编程空指针的一个小细节
- 二叉排序树(搜索树BST)-详解结点的删除
- hash table(完全散列实现的哈希表)
- hash table(用乘法散列法实现)