题目:https://www.luogu.org/problemnew/show/P2680

久违地1A了好高兴啊!

首先,要最大值最小,很容易想到二分;

判断当前的 mid 是否可行,需要看看有没有去掉一条边使满足的方案;

这就需要树上差分来找出每条边被几个超过 mid 的路线覆盖;

若有一条边正好被所有超过 mid 的路线覆盖,且去掉它之后最大的路线也能满足,就是可行的。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=3e5+;
int n,m,head[maxn],ct,cnt,st[maxn],ed[maxn],tag[maxn],lca[maxn],len[maxn];
int h[maxn],ans,mx,f[maxn][],dep[maxn],l,r,mid;
bool flag;
struct N{
int to,next,w;
N(int t=,int n=,int w=):to(t),next(n),w(w) {}
}edge[maxn<<];
void add(int x,int y,int z){edge[++ct]=N(y,head[x],z); head[x]=ct;}
void init(int x,int fa)
{
f[x][]=fa; dep[x]=dep[fa]+;
for(int i=;i<=;i++)f[x][i]=f[f[x][i-]][i-];
for(int i=head[x],u;i;i=edge[i].next)
if((u=edge[i].to)!=fa) h[u]=h[x]+edge[i].w, init(u,x);
}
int LCA(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int k=dep[x]-dep[y];
for(int i=;i<=;i++)
if(k&(<<i))x=f[x][i];
for(int i=;i>=;i--)
if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
if(x==y)return x;
return f[x][];
}
void dfs(int x)
{
for(int i=head[x],u;i;i=edge[i].next)
{
if((u=edge[i].to)==f[x][])continue;
dfs(u); if(flag)return;
if(tag[u]==cnt && mx-edge[i].w<=mid)flag=;
tag[x]+=tag[u];
}
}
bool ck()
{
cnt=; flag=;
memset(tag,,sizeof tag);
for(int i=;i<=m;i++)
if(len[i]>mid)
{
tag[st[i]]++; tag[ed[i]]++;
tag[lca[i]]-=; cnt++;
}
dfs();
return flag;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y,z;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
init(,);
for(int i=;i<=m;i++)
{
scanf("%d%d",&st[i],&ed[i]);
lca[i]=LCA(st[i],ed[i]);
len[i]=h[st[i]]+h[ed[i]]-*h[lca[i]];
mx=max(mx,len[i]);
}
l=,r=mx;
while(l<=r)
{
mid=(l+r)>>;
if(ck())ans=mid,r=mid-;
else l=mid+;
}
printf("%d",ans);
return ;
}

洛谷P2680 运输计划——树上差分的更多相关文章

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

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

  2. 洛谷 P2680 运输计划 解题报告

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

  3. 洛谷P2680 运输计划 [LCA,树上差分,二分答案]

    题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...

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

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

  5. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  6. 洛谷 P2680 运输计划(NOIP2015提高组)(BZOJ4326)

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

  7. 洛谷——P2680 运输计划

    https://www.luogu.org/problem/show?pid=2680 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每 ...

  8. [NOIP2015] 提高组 洛谷P2680 运输计划

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  9. 洛谷P2680 运输计划

    大概就是二分+树上差分... 题意:给你树上m条路径,你要把一条边权变为0,使最长的路径最短. 最大的最小,看出二分(事实上我并没有看出来...) 然后二分k,对于所有大于k的边,树上差分求出最长公共 ...

随机推荐

  1. Android Studio + Genymotion模拟器安装与配置

    一.Android studio 下载与安装 https://developer.android.google.cn/studio/index.html 进入谷歌官方链接下载Android studi ...

  2. python3 监控代码变化 自动重启 提高开发效率

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'Michael Liao' import os, sys, time, sub ...

  3. CSRF之Ajax请求

    A:Ajax提交数据是,携带的CSRF在data中: <form method="POST" action="/csrf.html"> {% csr ...

  4. C++ string 转整数

    使用 sstream 完成转换, #include <iostream> #include <string> #include <sstream> #include ...

  5. 【BZOJ 1202】 [HNOI2005]狡猾的商人 (加权并查集)

    题链:http://www.lydsy.com/JudgeOnline/problem.php?id=1202 Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪 ...

  6. 集训第四周(高效算法设计)D题 (区间覆盖问题)

    原题 UVA10020  :http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19688 经典的贪心问题,区间上贪心当然是右区间越 ...

  7. The Bells are Ringing(枚举)

    Description Perhaps you all have heard the mythical story about Tower of Hanoi (The details of this ...

  8. [bzoj3668][Noi2014][起床困难综合症] (按位贪心)

    Description 21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm 一直坚持与起床困难综合症作斗争.通过研究相关文献,他找 ...

  9. C语言学习<输入输出函数,函数的调用>

    #include <stdio.h> /* 输入输出函数的学习 函数的调用 2017.05.25 soulsjie */ //输入连个数字求最大值 void main(){ int Max ...

  10. [TyvjP1313] [NOIP2010初赛]烽火传递(单调队列 + DP)

    传送门 就是个单调队列+DP嘛. ——代码 #include <cstdio> ; , t = , ans = ~( << ); int q[MAXN], a[MAXN], f ...