noip2015day2-运输计划
题目描述
公元$ 2044 $年,人类进入了宇宙纪元。
\(L\) 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个星球之间,这 \(n-1\) 条航道连通了 \(L\) 国的所有星球。
小 \(P\) 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 \(u_i\) 号星球沿最快的宇航路径飞行到 \(v_i\) 号星球去。显然,飞船驶过一条航道 是需要时间的,对于航道\(j\),任意飞船驶过它所花费的时间为 \(t_j\),并且任意两艘飞船之 间不会产生任何干扰。
为了鼓励科技创新,\(L\) 国国王同意小 \(P\) 的物流公司参与 \(L\) 国的航道建设,即允许小 $P $把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。
在虫洞的建设完成前小 \(P\) 的物流公司就预接了 \(m\) 个运输计划。在虫洞建设完成后, 这 \(m\) 个运输计划会同时开始,所有飞船一起出发。当这 \(m\) 个运输计划都完成时,小 \(P\) 的 物流公司的阶段性工作就完成了。
如果小 \(P\) 可以自由选择将哪一条航道改造成虫洞,试求出小 \(P\) 的物流公司完成阶段性工作所需要的最短时间是多少?
Input
第一行包括两个正整数 \(n、m\),表示 \(L\) 国中星球的数量及小 \(P\) 公司预接的运输计划的数量,星球从 \(1\) 到 \(n\) 编号。
接下来 \(n-1\) 行描述航道的建设情况,其中第 \(i\) 行包含三个整数 \(a_i, b_i\) 和 \(t_i\),表示第\(i\)条双向航道修建在 \(a_i\) 与 \(b_i\) 两个星球之间,任意飞船驶过它所花费的时间为 \(t_i\)。
接下来 \(m\) 行描述运输计划的情况,其中第 \(j\) 行包含两个正整数 \(u_j\) 和 \(v_j\),表示第 \(j\)个 运输计划是从 \(u_j\) 号星球飞往 \(v_j\) 号星球。
数据保证 \(1≤u_i,v_i≤n,1<=n,m<=300000\)
数据保证 \(1≤a_i,b_i≤n\) 且 \(0≤t_i≤1000\)。
Output
输出 共\(1\)行,包含\(1\)个整数,表示小\(P\)的物流公司完成阶段性工作所需要的最短时间。
Sample Input
6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
Sample Output
11
首先,看到了最大值最小就很自然的想到了二分答案。
嗯,二分是很显然的。。。。
那么,我们该如何\(check\)呢?,对于两点间路径已经小于当前\(x\)的路径可以直接忽视掉。
那么剩下来的路径就是大于当前\(x\)的路径了,对于这些路径我们需要去掉一条边是所有的路径中最大值最小。
即,我们需要减去路径交集中最大的边。
这个操作是很显然的,因为只有减得越多才可以剩的越少。
现在,我们需要做的就是求出所有路径的交集了?
怎么求呢?我们可以利用树上差分来进行求解。
我们需要将边转换到点上,那么我们该如何转换呢?
由于一条边的节点一定是父亲节点和儿子节点之分。
而儿子节点所对应的边只有一条,所以我们将边转移到子节点上。
当加入一条路径\(a,b\)时,设\(LCA\)为\(a,b\)的\(lca\),则\(Sum[a]++,Sum[b]++,Sum[LCA]-=2\)。
我们统计答案时若当前节点的\(Sum\)值为不满足条件的路径个数,说明该节点所对应的边为所有路径的交集,
更新答案即可。。。
最后看一下最长的路径减去路径上的最大值是否\(<=\)当前\(x\)即可。
不过这道题的数据较大,普通的算法容易被卡掉。
那么,我们就需要一些优化。。。
1.优化二分上下界:
\(L=\)最长的路径长度减去最大的边权,\(R=\)最长的路径长度。
这样二分的次数保证在\(10\)以内。
2.避免递归:
由于统计答案时,我们需要递归求解,而递归是有常数的,
我们又发现一个节点的值只和其子树有关,而子树在\(dfs\)序中时保证子节点编号大于根节点编号。
于是,我们可以利用\(dfs\)序倒着更新\(Sum\)值。
代码如下
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define reg register
#define Raed Read
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,G,x) for(int i=(G).Head[x]; i; i=(G).Nxt[i])
inline char G1() {
static const int LEN=2000005;
static char U[LEN],*T=U,*E=U;
if(T==E)T=U,E=U+fread(U,1,LEN,stdin);
return T==E?EOF:*T++;
}
inline int Read(void) {
int res=0,f=1;
char c;
while(c=G1(),c<48||c>57)if(c=='-')f=0;
do res=(res<<3)+(res<<1)+(c^48);
while(c=G1(),c>=48&&c<=57);
return f?res:-res;
}
template<class T>inline bool Min(T &a,T const&b) {
return a>b ?a=b,1:0;
}
template<class T>inline bool Max(T &a,T const&b) {
return a<b?a=b,1:0;
}
const int N=3e5+5,M=3e5+5,mod=1e9+7;
bool MOP1;
int n,m,A[N],B[N],TT[M];
struct Link_list {
int Tot,Head[N],to[M<<1],Nxt[M<<1],cost[M<<1];
inline void clear(void) {
Tot=0;
memset(Head,0,sizeof Head);
}
inline void AddEdgepair(int a,int b,int c) {
to[++Tot]=b,cost[Tot]=c,Nxt[Tot]=Head[a],Head[a]=Tot;
to[++Tot]=a,cost[Tot]=c,Nxt[Tot]=Head[b],Head[b]=Tot;
}
} G;
int Fa[M],dep[M],top[M],sz[M],son[M],Dis[M],LCA[N],cnt,Id[N];
void dfs1(int x,int f) {
Id[++cnt]=x;
dep[x]=dep[f]+1,Fa[x]=f,sz[x]=1;
erep(i,G,x) {
int y=G.to[i];
if(y==f)continue;
Dis[y]=Dis[x]+G.cost[i];
TT[y]=G.cost[i];
dfs1(y,x),sz[x]+=sz[y];
if(sz[y]>sz[son[x]])son[x]=y;
}
}
void dfs2(int x,int f) {
top[x]=f;
if(son[x])dfs2(son[x],f);
else return;
erep(i,G,x) {
int y=G.to[i];
if(y==Fa[x]||y==son[x])continue;
dfs2(y,y);
}
}
inline int lca(int x,int y) {
while(top[x]!=top[y]) {
if(dep[top[x]]>dep[top[y]])x=Fa[top[x]];
else y=Fa[top[y]];
}
return dep[x]<dep[y]?x:y;
}
int res,tot,Sum[N];
inline bool check(int x) {
res=-1,tot=0;
rep(i,1,n)Sum[i]=0;
rep(i,1,m) {
if(Dis[A[i]]+Dis[B[i]]-2*Dis[LCA[i]]<=x)continue;
tot++,Sum[A[i]]++,Sum[B[i]]++,Sum[LCA[i]]-=2;
}
drep(i,n,1) {
int u=Id[i];
erep(i,G,u) {
int y=G.to[i];
if(y==Fa[u])continue;
Sum[u]+=Sum[y];
}
if(Sum[u]==tot)Max(res,TT[u]);
}
if(res==-1)return false;
rep(i,1,m) {
if(Dis[A[i]]+Dis[B[i]]-2*Dis[LCA[i]]<=x)continue;
if(Dis[A[i]]+Dis[B[i]]-2*Dis[LCA[i]]-res>x)return false;
}
return true;
}
int Ma;
inline void solve(void) {
int L=0,R=0,Ans=0;
rep(i,1,m)Max(R,Dis[A[i]]+Dis[B[i]]-2*Dis[LCA[i]]);
L=R-Ma;
while(L<=R) {
int mid=(L+R)>>1;
if(check(mid))Ans=mid,R=mid-1;
else L=mid+1;
}
printf("%d\n",Ans);
}
bool MOP2;
inline void _main(void) {
n=Read(),m=Read();
int f=1;
ret(i,1,n) {
int a=Read(),b=Read(),c=Read();
Max(Ma,c),G.AddEdgepair(a,b,c);
}
dfs1(1,0),dfs2(1,1);
rep(i,1,m)A[i]=Read(),B[i]=Read(),LCA[i]=lca(A[i],B[i]);
solve();
}
signed main() {
_main();
return 0;
}
noip2015day2-运输计划的更多相关文章
- bzoj 4326: NOIP2015 运输计划
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...
- noip2015 运输计划
描述 公元 2044 年,人类进入了宇宙纪元.L 国有 nn 个星球,还有 n−1n−1 条双向航道,每条航道建立在两个星球之间,这 n−1n−1 条 航道连通了 L 国的所有星球. 小 P 掌管一家 ...
- 【bzoj4326】[NOIP2015]运输计划
题目描述 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该 ...
- [题解]vijos 运输计划
Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...
- NOIP2015 运输计划(bzoj4326)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 886 Solved: 574[Submit][Status] ...
- UOJ #150 【NOIP2015】 运输计划
题目描述 公元 \(2044\) 年,人类进入了宇宙纪元. \(L\) 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个星球之间,这 \(n-1\) 条航道连通了 \(L ...
- [bzoj4326][NOIP2015]运输计划
Description 公元2044年,人类进入了宇宙纪元. 国有个星球,还有条双向航道,每条航道建立在两个星球之间,这条航道连通了国的所有星球. 小掌管一家物流公司,该公司有很多个运输计划,每个运输 ...
- 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 703 Solved: 461[Submit][Status] ...
- [NOIP2015] 提高组 洛谷P2680 运输计划
题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...
- [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划
[BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划 试题描述 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− ...
随机推荐
- 翻页的时候更改URL地址
要求点击第一页是url+p1html,点击第二页是url+p2html等等 $("body").on('click','#w_tagPage a[wid]',function(){ ...
- TTTTTTTTTTTTTT poj 1127 Jack Straws 线段相交+并查集
题意: 有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通) #include <iostream> #include <cstdio> ...
- R_针对churn数据用id3、cart、C4.5和C5.0创建决策树模型进行判断哪种模型更合适
data(churn)导入自带的训练集churnTrain和测试集churnTest 用id3.cart.C4.5和C5.0创建决策树模型,并用交叉矩阵评估模型,针对churn数据,哪种模型更合适 决 ...
- 前端学习之三——jquery选择器
Jquery中的选择器分为几大类:基本过滤选择器,层次选择器,内容过滤选择器,可见性过滤选择器,属性过滤选择器,子元素过滤选择器,表单对象选择器和表单对象属相过滤选择器. 1.非基本过滤选择器,一般需 ...
- Docker入门-数据挂载
Docker数据管理 在容器中管理数据主要有两种方式: 数据卷(Volumes) 挂载主机目录(Bind mounts) 数据卷 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很 ...
- 选题 Scrum立会报告+燃尽图 04
本次作业要求参见:edu.cnblogs.com/campus/nenu/2019fall/homework/9913 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 徐丽君队名:胜利点 二.S ...
- android 模糊背景 异型背景
模糊算法参考: http://blog.csdn.net/markl22222/article/details/10313565 网上很多,这东西是个概念理解,没有什么新鲜的. 轮子有现成的,模糊算法 ...
- CSS样式属性单词之Left
通常left单独在CSS中设置无效,需要在使用position属性下使用才能生效起作用.left左靠多少距离(距离左边多少)的作用. left 一.left认识与语法 left翻译:左边,左 在CSS ...
- flutter 图片圆角
return Center( child: Container( padding: EdgeInsets.only(left: 10), width: 120, height: 80, child: ...
- Windows10安装秘钥大全
Windows10官方镜像下载地址: 点击下载 老毛桃U盘启动制作:点击下载 秘钥大全 家庭版: Core 家庭版:YTMG3-N6DKC-DKB77-7M9GH-8HVX7 单语言家庭版:BT79Q ...