P2680 运输计划

链接

分析:

  二分+树上差分。

  首先可以二分一个答案,那么所有比这个答案大的路径,都需要减去些东西才可以满足这个答案。

  那么减去的这条边一定在所有的路径的交集上。

  那么如果求快速的求出这个交集并判断呢,树剖可以,把所有大于的路径都标记一下,然后判断,复杂度太大了。

  于是用到了树上差分,get新技能。

  在两个端点出标记+1,在lca出标记-2,然后从叶子节点往上更新,对于一条边是交集,那么它标记的次数一定是大于这个答案的个数。然后判断是否满足即可。

  各种优化:1、L,R的范围,2、可以按dis排序,发现没什么用。

代码

 // luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype> using namespace std; const int N = ;
struct Edge{
int nxt,to,w;
Edge() {}
Edge(int a,int b,int c) {to = a,w = b,nxt = c;}
}e[];
struct Que{
int u,v,lca,dis;
bool operator < (const Que &A) const {
return dis > A.dis;
}
}q[N];
int head[N],tot;
int deth[N],fa[N],num[N],dis[N],val[N],f[N][],tag[N];
int n,m,dfs_time; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2)?EOF:*p1++;
}
inline int read() {
int x = ,f = ;char ch = nc();
for (; !isdigit(ch); ch=nc()) if(ch=='-') f=-;
for (; isdigit(ch); ch=nc()) x=x*+ch-'';
return x * f;
}
void add_edge(int u,int v,int w) {
e[++tot] = Edge(v,w,head[u]);head[u] = tot;
e[++tot] = Edge(u,w,head[v]);head[v] = tot;
}
void dfs(int u,int fa) {
num[++dfs_time] = u;
deth[u] = deth[fa] + ;
f[u][] = fa;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v == fa) continue;
dis[v] = dis[u] + e[i].w;
val[v] = e[i].w;
dfs(v,u);
}
}
void init() {
for (int j=; j<=; ++j)
for (int i=; i<=n; ++i)
f[i][j] = f[f[i][j-]][j-];
}
int Lca(int u,int v) {
if (deth[u] < deth[v]) swap(u,v);
int d = deth[u] - deth[v];
for (int i=; i>=; --i)
if (d & ( << i)) u = f[u][i];
if ( u == v ) return u;
for (int i=; i>=; --i)
if (f[u][i] != f[v][i])
u = f[u][i],v = f[v][i];
return f[u][];
}
bool check(int x) {
memset(tag,,sizeof(tag));
int limit = ,cnt = ;
for (int i=; i<=m; ++i) {
if (q[i].dis > x) { // 找到所有大于x的
tag[q[i].u] ++; tag[q[i].v] ++; tag[q[i].lca] -= ; // 差分
limit = max(limit,q[i].dis - x); // 最少减去多少
cnt ++;
}
}
if (!cnt) return true; //如果没有大于x的,直接返回true,加上这句快了不少。
for (int i=n; i>=; --i)
tag[f[num[i]][]] += tag[num[i]];
for (int i=; i<=n; ++i)
if (val[i] >= limit && tag[i] == cnt) return true;
return false;
}
int main () {
n = read(),m = read();
int L = ,R = ;
for (int i=; i<n; ++i) {
int u = read(),v = read(),w = read();
add_edge(u,v,w);
L = max(L,w);
}
dfs(,);
init();
for (int i=; i<=m; ++i) {
q[i].u = read(),q[i].v = read();
q[i].lca = Lca(q[i].u,q[i].v);
q[i].dis = dis[q[i].u] + dis[q[i].v] - dis[q[i].lca] * ;
R = max(R, q[i].dis);
}
// sort(q+1,q+m+1);
int ans = R;
while ( L <= R ) {
int mid = ( L + R ) / ;
if (check(mid)) ans = mid,R = mid - ;
else L = mid + ;
}
cout << ans;
return ;
}

P2680 运输计划(二分+树上差分)的更多相关文章

  1. 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)

    P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...

  2. Luogu P2680 运输计划(二分+树上差分)

    P2680 运输计划 题意 题目背景 公元\(2044\)年,人类进入了宇宙纪元. 题目描述 公元\(2044\)年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道 ...

  3. P2680 运输计划 二分+树上差分

    又咕咕了几天\(QwQ\) 思路:二分+树上差分 提交:\(\geq5\)次 错因:\(lca\)写错+卡了很久常数(哪位大佬帮我康康,有更好的写法请指出\(QwQ\)) 题解: 我们先将原问题转化为 ...

  4. 洛谷P2680 运输计划(树上差分+二分)

    传送门 考虑树上乱搞 首先这是满足二分性质的,如果在某个时间可以完成工作那么比他更长的时间肯定也能完成工作 然后考虑二分,设当前答案为$mid$,如果有一条链的长度大于$mid$,那么这条链上必须得删 ...

  5. BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1930  Solved: 1231[Submit][Statu ...

  6. NOIP2015Day2T3运输计划(二分+树上差分)

    做了这么多NOIPTG的题,这是唯一 一道一眼秒的T3(有时候T2还不会做QAQ)... 题目大意就不说了QWQ 思路大概是:啊最大值最小化,来个二分.检验mid的话,显然就是用最长路径减去所有边权& ...

  7. 【Luogu】P2680运输计划(树上差分+二分)

    题目链接 总体思路……怎么说呢……是个暴力吧…… 首先用倍增预处理出每条路径的长度. 然后按长度把路径排序. 然后二分答案.对于当前答案mid检验,怎么检验呢? 首先差分把所有长度比mid大的链上除了 ...

  8. [luogu]P2680 运输计划[二分答案][树上差分]

    [luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...

  9. P2680 运输计划[二分+LCA+树上差分]

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

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

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

随机推荐

  1. Asp.net防御XSS攻击组件库

    一.AntiXss 翻看mvc4高级编程,偶看到作者强烈推荐使用AntiXss防御XSS攻击,收集资料看下. 目前类库已融入到.netframework中,类库主页不再更新. 使用方法:使用Nuget ...

  2. [RDLC]心得整理(一)

    2014年在做项目的时候, 过用过RDLC, 之后便在没有使用过了. 最近又有项目使用rdlc, 感觉有些陌生,然后重新阅读了以前的笔记,想做一下整理. 常见问题: 1. 为什么rdlc报表出来的pd ...

  3. [javascript]什么是闭包?

    http://www.zcfy.cc/article/master-the-javascript-interview-what-is-a-closure-2127.html

  4. polyfill 一个解决兼容的绝佳方案

    polyfill为何物 Polyfill你可以理解为“腻子”,就是装修的时候,可以把缺损的地方填充抹平. 举个例子,html5的storage(session,local), 不同浏览器,不同版本,有 ...

  5. Oracle三种循环例题:打印九九乘法表

    数据库SQL三种循环语句(For.While.Loop) --如果要将执行结果输出,需要先执行 setserveroutput on 命令,在窗口里显示服务器输出信息 set serveroutput ...

  6. Visual Studio 编辑器打开项目后,一直提醒Vs在忙,解决方法

    今天打开VS2015后,因为这个解决中有很项目,突然就一直现在加载中,点击VS提示在忙,怎么破那?请往下看 第一种方法 1.关闭VS: 2.去C:\Users\<your users name& ...

  7. 【转】Android Support 包里究竟有什么

    随着 Android 5.0 Lollipop 的发布,Android 又为我们提供了更多的支持包,但是我相信大部分开发者都同我之前一样不知道这些包里究竟有些什么东西,我们应该在什么时候使用它.现在, ...

  8. leetCode没那么难啦 in Java (一)

    前言    感觉写博客是一个很耗心力的东西T_T,简单的写了似乎没什么用,复杂的三言两语也只能讲个大概,呸呸...怎么能有这些消极思想呢QAQ!那想来想去,先开一个leetcode的坑,虽然已经工作了 ...

  9. git中.gitignore 文件

    现在项目的根目录放了 .gitignore 文件,并且git远程仓库的项目根目录已经有了 logs文件夹. 由于每次本地运行项目,都会生成新的log文件,但是我并不想提交logs文件夹里面的内容,所以 ...

  10. redis事务中的WATCH命令和基于CAS的乐观锁

    转自:http://blog.sina.com.cn/s/blog_ae8441630101cgy3.html 在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能. ...