NOIP2015_提高组Day2_3_运输计划
这题思路很简单;
先对每个询问求距离,对距离由大到小排序,
二分最小距离,验证是否可行,验证时用差分处理;
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iomanip>
#include<map>
#include<set>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
using namespace std;
#define LL long long
#define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
#define max(x,y) ((x)<(y)?(y):(x))
#define min(x,y) ((x)<(y)?(x):(y))
#define FILE "1"
#define pii pair<int,int>
const int maxn=,inf=;
int read(){
int x=;bool flag=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')flag=;ch=getchar();}
while(ch<=''&&ch>=''){x=x*+ch-'';ch=getchar();}
return flag?-x:x;
}
int n,m;
struct node{
int y,next,v;
}e[maxn<<];
int linkk[maxn],len=,fa[maxn],w[maxn],dep[maxn],top[maxn],siz[maxn],son[maxn],d[maxn];
void insert(int x,int y,int v){
e[++len].y=y;
e[len].v=v;
e[len].next=linkk[x];
linkk[x]=len;
}
int q[maxn],tail=,head=;
void dfs(int x){
siz[x]=;
for(int i=linkk[x];i;i=e[i].next){
if(e[i].y==fa[x])continue;
fa[e[i].y]=x;w[e[i].y]=e[i].v;dep[e[i].y]=dep[x]+;
dfs(e[i].y);
siz[x]+=siz[e[i].y];
if(siz[e[i].y]>siz[son[x]])son[x]=e[i].y;
}
}
void dfs2(int x){
if(son[x]){
top[son[x]]=top[x];
d[son[x]]=d[x]+w[son[x]];
dfs2(son[x]);
}
for(int i=linkk[x];i;i=e[i].next){
if(e[i].y==fa[x]||e[i].y==son[x])continue;
top[e[i].y]=e[i].y;
d[e[i].y]=;
dfs2(e[i].y);
}
}
pii lca(int x,int y){
int u,v;
int sum=;
while(x!=y){
u=top[x],v=top[y];
if(u==v)return make_pair((dep[x]>dep[y]?y:x),sum+abs(d[x]-d[y]));
if(dep[u]>dep[v]){swap(x,y);swap(u,v);}
sum+=d[y]+w[v];
y=fa[v];
}
return make_pair(x,sum);
}
struct Node{
int x,y,v,f;
bool operator<(const Node &b)const{return v>b.v;}
}a[maxn];
int vis[maxn];
int maxx=,flag=;
void Dfs(int x){
for(int i=linkk[x];i;i=e[i].next){
if(e[i].y==fa[x])continue;
Dfs(e[i].y);
vis[x]+=vis[e[i].y];
}
if(vis[x]==flag)maxx=max(maxx,w[x]);
}
int work(int mid){
memset(vis,,sizeof(vis));
for(int i=;i<=mid;i++)vis[a[i].x]++,vis[a[i].y]++,vis[a[i].f]-=;//比较暴力的差分
//可以利用树链剖分将树划分成线段,在上面做差分,常数要比这个小的多,实测结果是#20会超
maxx=;flag=mid;Dfs();
return maxx;
}
void slove(){
n=read();m=read();
int x,y,v;
up(i,,n){
x=read(),y=read(),v=read();
insert(x,y,v);insert(y,x,v);
}
dfs();top[]=;
dfs2();
pii temp;
up(i,,m){
a[i].x=read(),a[i].y=read();
temp=lca(a[i].x,a[i].y);
a[i].v=temp.second;a[i].f=temp.first;
}
sort(a+,a+m+);
int left=,right=m,mid,ans=inf;//也可以1-a[1].v这样枚举,加个记忆化就好;
while(left<=right){
mid=(left+right)>>;
int fee=a[].v-work(mid);
if(fee>a[mid+].v)right=mid-;
else left=mid+;
ans=min(ans,max(fee,a[mid+].v));
}
cout<<ans<<endl;
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
slove();
return ;
}
//如果window下评测注意加个开栈
NOIP2015_提高组Day2_3_运输计划的更多相关文章
- 【NOIP2015提高组】运输计划
https://daniu.luogu.org/problem/show?pid=2680 使完成所有运输计划的时间最短,也就是使时间最长的运输计划耗时最短.最大值最小问题考虑用二分答案,每次chec ...
- 题解——洛谷 P2680 NOIP提高组 2015 运输计划
树上差分加上二分答案 详细题解待填坑 #include <cstdio> #include <algorithm> #include <cstring> using ...
- 题解 【luogu P2680 NOIp提高组2015 运输计划】
题目链接 题解 题意 一棵树上有\(m\)条路径,可以将其中一条边的权值改为0,问最长的路径最短是多少 分析 最短的路径最长自然想到二分最长路径,设其为\(dis\) 关键在于如何check chec ...
- 【NOIP】提高组2015 运输计划
[题意]n个点的树,m条链,求将一条边的权值置为0使得最大链长最小. [算法]二分+树上差分 [题解] 最大值最小化问题,先考虑二分最大链长. 对所有链长>mid的链整体+1(树上差分). 然后 ...
- JZYZOJ1452 NOIP2015_提高组Day2_1_跳石头
http://172.20.6.3/Problem_Show.asp?id=1452很简单的二分,最开始以为是优先队列,想了想发现优先队列是有情况不能达到最优的,所以二分+贪心处理,在贪心check的 ...
- [NOIP2013提高组]货车运输
题目:洛谷P1967.Vijos P1843.codevs3287. 题目大意:有n个城市m条道路,每条道路有一个限重,规定货车运货不能超过限重.有一些询问,问你两个城市之间一次最多能运多少重的货(可 ...
- [NOIP2013 提高组] 货车运输
前言 使用算法:堆优化 \(prim\) , \(LCA\) . 题意 共有 \(n\) 个点,有 \(m\) 条边来连接这些点,每条边有权值.有 \(q\) 条类似于 \(u\) \(v\) 询问, ...
- 【数据结构】运输计划 NOIP2015提高组D2T3
[数据结构]运输计划 NOIP2015提高组D2T3 >>>>题目 [题目描述] 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航 ...
- cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分
2109. [NOIP 2015] 运输计划 ★★★☆ 输入文件:transport.in 输出文件:transport.out 简单对比时间限制:3 s 内存限制:256 MB [题 ...
随机推荐
- 牛客网 牛客练习赛11 D.求距离
D.求距离 链接:https://www.nowcoder.com/acm/contest/59/D来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言6 ...
- 蚂蚁金服CTO程立:金融级分布式交易的技术路径
总结: 强一致的微服务 oceanbase里面的投票选举以及多中心多地部署 单元化市异地多活的基础.支付宝是异地多活和容灾结合,而容灾的基础也是单元化.基于单元化进行单元的调度.部署.容灾. 混合云架 ...
- OS | Process
linux多进程 1. fork()创建进程,创建一份父进程的拷贝:在父进程中返回的是子进程id,在子进程中返回的是0:失败时返回-1: 2. fork()经常和exec()结合,exec() 覆盖了 ...
- javascript好文---深入理解定位父级offsetParent及偏移大小
前面的话 偏移量(offset dimension)是javascript中的一个重要的概念.涉及到偏移量的主要是offsetLeft.offsetTop.offsetHeight.offsetWid ...
- Android---简单的动画
- Android View 绘制流程(Draw) 完全解析
前言 前几篇文章,笔者分别讲述了DecorView,measure,layout流程等,接下来将详细分析三大工作流程的最后一个流程——绘制流程.测量流程决定了View的大小,布局流程决定了View的位 ...
- C 标准库 - <stdarg.h>
C 标准库 - <stdarg.h> 简介 stdarg.h 头文件定义了一个变量类型 va_list 和三个宏,这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数. 可变参 ...
- 【Java编程】Java在dos窗体编译与运行的批处理
近期在Java编程过程中,常常使用到dos窗体对程序进行编译与执行. 可是不方便之处在于每次都要输入命令进入将要编译的程序的文件夹(事实上也有简单的方法,在文章末尾给出).于是编写了一个配置文件,能够 ...
- MySQL数据导入与导出
http://blog.chinaunix.net/uid-23354495-id-3188029.html mysql备份脚本之select into outfile
- Node.js知识点学习
Node.js知识点学习 一.基本概念 Node.js,或者 Node,是一个可以让 JavaScript 运行在服务器端的平台.可以说,Node.js开创了javascript模块化开发的先河,早期 ...