这题思路很简单;

先对每个询问求距离,对距离由大到小排序,

二分最小距离,验证是否可行,验证时用差分处理;

#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_运输计划的更多相关文章

  1. 【NOIP2015提高组】运输计划

    https://daniu.luogu.org/problem/show?pid=2680 使完成所有运输计划的时间最短,也就是使时间最长的运输计划耗时最短.最大值最小问题考虑用二分答案,每次chec ...

  2. 题解——洛谷 P2680 NOIP提高组 2015 运输计划

    树上差分加上二分答案 详细题解待填坑 #include <cstdio> #include <algorithm> #include <cstring> using ...

  3. 题解 【luogu P2680 NOIp提高组2015 运输计划】

    题目链接 题解 题意 一棵树上有\(m\)条路径,可以将其中一条边的权值改为0,问最长的路径最短是多少 分析 最短的路径最长自然想到二分最长路径,设其为\(dis\) 关键在于如何check chec ...

  4. 【NOIP】提高组2015 运输计划

    [题意]n个点的树,m条链,求将一条边的权值置为0使得最大链长最小. [算法]二分+树上差分 [题解] 最大值最小化问题,先考虑二分最大链长. 对所有链长>mid的链整体+1(树上差分). 然后 ...

  5. JZYZOJ1452 NOIP2015_提高组Day2_1_跳石头

    http://172.20.6.3/Problem_Show.asp?id=1452很简单的二分,最开始以为是优先队列,想了想发现优先队列是有情况不能达到最优的,所以二分+贪心处理,在贪心check的 ...

  6. [NOIP2013提高组]货车运输

    题目:洛谷P1967.Vijos P1843.codevs3287. 题目大意:有n个城市m条道路,每条道路有一个限重,规定货车运货不能超过限重.有一些询问,问你两个城市之间一次最多能运多少重的货(可 ...

  7. [NOIP2013 提高组] 货车运输

    前言 使用算法:堆优化 \(prim\) , \(LCA\) . 题意 共有 \(n\) 个点,有 \(m\) 条边来连接这些点,每条边有权值.有 \(q\) 条类似于 \(u\) \(v\) 询问, ...

  8. 【数据结构】运输计划 NOIP2015提高组D2T3

    [数据结构]运输计划 NOIP2015提高组D2T3 >>>>题目 [题目描述] 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航 ...

  9. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...

随机推荐

  1. 计蒜客 UCloud 的安全秘钥(随机化+Hash)

    题目链接 UCloud 的安全秘钥 对于简单的版本,我们直接枚举每个子序列,然后sort一下判断是否完全一样即可. #include <bits/stdc++.h> using names ...

  2. OS | Socket

    TCP 创建socket: int socket(int domain, int type, int protocol); AF = Address FamilyPF = Protocol Famil ...

  3. 327. Count of Range Sum

    /* * 327. Count of Range Sum * 2016-7-8 by Mingyang */ public int countRangeSum(int[] nums, int lowe ...

  4. nginx 自签名https

    繁杂的命令,以下准备写好的sh,拷贝https.sh文件,设置执行权限:chmod u+x https.sh #!/bin/sh # create self-signed server certifi ...

  5. 【spring mvc】后台spring mvc接收List参数报错如下:org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.List]: Specified class is an interface

    后台spring mvc接收List参数报错如下:org.springframework.beans.BeanInstantiationException: Failed to instantiate ...

  6. Neural Networks and Deep Learning学习笔记ch1 - 神经网络

    近期開始看一些深度学习的资料.想学习一下深度学习的基础知识.找到了一个比較好的tutorial,Neural Networks and Deep Learning,认真看完了之后觉得收获还是非常多的. ...

  7. 5.4 heapq--堆队列算法

    本模块实现了堆队列算法,也叫作优先级队列算法.堆队列是一棵二叉树.而且拥有这样特点,它的父节点的值小于等于不论什么它的子节点的值,假设採用数组array实现,能够把它们的关系表示为:heap[k] & ...

  8. Error building Player: Win32Exception: ApplicationName=&#39;E:/adt-20140702/sdk\tools\zipalign.exe&#39;, Com

    1.原因 更新sdk后报错..由于版本号不同,zipalign.exe所处路径不同 2.解决的方法 在sdk路径下搜索zipalign.exe .然后拷贝到报错内容中制定的路径即可了.

  9. CCNP路由实验之十二 MPLS

     个.第3个数据包„„同样的操作.包含查询路由表.重写MAC地址,CRC校验等. 系列路由器.或者12000系列路由器. Netflow switching 通过一种标准的交换机制,处理了流的第一 ...

  10. mysql drop table命令使用总结

    drop性能 drop table(innodb引擎) 数量2000w,只需要5m