这题思路很简单;

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

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

#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. CMDB与自动化运维,一切尽在掌握中?

    生产力跟不上生产的速度时,就会出现很多问题,如何针对问题进行处理,制定什么样的计划,如何解决就是需要思考的难点? T运维的分类 IT运维,指的是对已经搭建好的网络,软件,硬件进行维护.运维领域也是细分 ...

  2. codevs——1008 选数

    1008 选数 2002年NOIP全国联赛普及组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 已知 n ...

  3. 多协议底层攻击工具Yesinia

    多协议底层攻击工具Yesinia   Yesinia是一款底层协议攻击工具.它提供多种运行模式,如终端文本模式.GTK图形模式.NCurses模式.守护进程模式.它利用各种底层协议的漏洞实施攻击,支持 ...

  4. Java 正则表达式的使用

    Java 正则表达式的使用 java.util.regex 包主要包括以下三个类: Pattern 类: pattern 对象是一个正则表达式的编译表示.Pattern 类没有公共构造方法.要创建一个 ...

  5. Leetcode总结之Graph

    package Graph; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections ...

  6. 【IntelliJ IDEA】在idea上安装使用svn

    1.在电脑上安装SVN 下载地址:64位SVN下载 然后一路next,安装完成即可. 如果忘记勾选第二个,可以重新点击安装包  重新安装,然后选择modify,然后勾选command line cli ...

  7. C#中二进制,八进制,十六进制到十进制的相互转换

    1.十进制数字向二进制,八进制,十六进制字符串的转换,使用函数 Convert.ToString(int value, int toBase): 它可以把一个数字转换为不同进制数值的字符串格式,其中t ...

  8. 实现TextView中link的点击效果

    朋友们,你们在TextView处理link的时候是不是一直被苦逼的android默认的方式困扰?每次点击link的时候,点击效果是整个textview来响应.非常烂吧?原因就不多赘述了. 那么以下这个 ...

  9. js 字符串常用方法

    数组方面 1.push:向数组尾部增加内容,返回的是新数组的长度. var arr = [1,2,3]; console.log(arr); var b = arr.push(4); console. ...

  10. 数据结构与算法系列----AC自己主动机

    一:概念 首先简要介绍一下AC自己主动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之中的一个.一个常见的样例就是给出n个单词,再给出一段 ...