树链剖分-Hello!链剖-[NOIP2015]运输计划-[填坑]
This article is made by Jason-Cow.
Welcome to reprint.
But please post the writer's address.
http://www.cnblogs.com/JasonCow/
[NOIP2015]运输计划 Hello!链剖。你好吗?
题意:
给出一棵n个节点的带权树,m对树上点对
现在允许删除一条边,(权值修改为0)
输出: 最小化的点对间最大距离
1.链剖
2.树上差分
3.二分
链剖我就不多说了,就是两dfs
注意:要在dfs1中多维护一个dis[x],x到root的距离,顺便记录一下w[x]!
void dfs1(int u,int f){
fa[u]=f,dep[u]=dep[f]+,siz[u]=;
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=f){
w[v]=E[i].w,dis[v]=dis[u]+E[i].w;
dfs1(v,u);
siz[u]+=siz[v];
if(!son[u]||siz[v]>siz[son[u]])son[u]=v;
}
}
}
dfs1
void dfs2(int u,int t){
dfn[u]=++idx,top[u]=t;
if(son[u])dfs2(son[u],t);
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=fa[u]&&v!=son[u])dfs2(v,v);
}
}
dfs2
树上差分,先差分,后dfs上放(95分的根本原因,不过好写)
细节:add(l,r) <=> cf[l]++ , cf[r+1]--; 再上放
void modify(int u,int f){
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=f){
modify(v,u);
cf[u]+=cf[v];
}
}
}
modify
二分,很显然好吗。
bool check(int x){
int cnt=,maxcost=;
memset(cf,,sizeof(cf));
for(int i=;i<=m;i++)
if(a[i].dis>x){
cnt++;
maxcost=max(maxcost,a[i].dis-x);
cf[a[i].s]++,cf[a[i].t]++;cf[a[i].lca]-=;
}
if(cnt==)return false;
modify(,);
for(int i=;i<=n;i++)
if(cf[i]==cnt && w[i]>=maxcost)
return false;
return true;
}
check
这个还不是正解,因为被卡常了,于是我就卡数据,嘿嘿嘿~~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
const int N=3e5+,M=6e5+;
inline void _(int &ans){
ans=;char x=getchar(),f=;
while(x<''||x>''){if(x=='-')f=;x=getchar();}
while(x>=''&&x<='')ans=ans*+x-'',x=getchar();
if(f)ans=-ans;
} int head[N],tot,n,m;
int dfn[N],top[N],siz[N],son[N],dep[N],fa[N],idx;
int dis[N],w[N],cf[N];
struct node{int v,w,next;}E[M];
struct ask{int lca,dis,s,t;}a[N];
void add(int u,int v,int w){E[++tot]=(node){v,w,head[u]},head[u]=tot;}
void edge(int u,int v,int w){add(u,v,w),add(v,u,w);} void dfs1(int u,int f){
fa[u]=f,dep[u]=dep[f]+,siz[u]=;
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=f){
w[v]=E[i].w,dis[v]=dis[u]+E[i].w;
dfs1(v,u);
siz[u]+=siz[v];
if(!son[u]||siz[v]>siz[son[u]])son[u]=v;
}
}
} void dfs2(int u,int t){
dfn[u]=++idx,top[u]=t;
if(son[u])dfs2(son[u],t);
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=fa[u]&&v!=son[u])dfs2(v,v);
}
} void lca(int s,int t,int i){
int x=s,y=t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
a[i].lca=x;
a[i].dis=dis[s]+dis[t]-*dis[x];
} void modify(int u,int f){
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=f){
modify(v,u);
cf[u]+=cf[v];
}
}
} bool check(int x){
int cnt=,maxcost=;
memset(cf,,sizeof(cf));
for(int i=;i<=m;i++)
if(a[i].dis>x){
cnt++;
maxcost=max(maxcost,a[i].dis-x);
cf[a[i].s]++,cf[a[i].t]++;cf[a[i].lca]-=;
}
if(cnt==)return false;
modify(,);
for(int i=;i<=n;i++)
if(cf[i]==cnt && w[i]>=maxcost)
return false;
return true;
} int _u,_v,_w,_s,_t;
int l,r,mid;
int main(){
_(n),_(m);//scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
_(_u),_(_v),_(_w);//scanf("%d%d%d",&_u,&_v,&_w);
edge(_u,_v,_w);
}
dfs1(,);
dfs2(,);
for(int i=;i<=m;i++){
_(_s),_(_t);//scanf("%d%d",&_s,&_t);
a[i].s=_s,a[i].t=_t;
lca(_s,_t,i);
r=max(r,a[i].dis);
}
l=max(,r-);//95分
while(l<=r){
int mid=(l+r)>>;
if(check(mid))l=mid+;
else r=mid-;
}
printf("%d\n",l);
return ;
}
树链剖分-Hello!链剖-[NOIP2015]运输计划-[填坑]的更多相关文章
- 数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划
2109. [NOIP2015] 运输计划 ★★★ 输入文件:transport.in 输出文件:transport.out 简单对比时间限制:1 s 内存限制:256 MB [题目描 ...
- [NOIP2015]运输计划 线段树or差分二分
目录 [NOIP2015]运输计划 链接 思路1 暴力数据结构 思路2 二分树上差分 总的 代码1 代码2 [NOIP2015]运输计划 链接 luogu 好久没写博客了,水一篇波. 思路1 暴力数据 ...
- NOIP2015 运输计划(bzoj4326)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 886 Solved: 574[Submit][Status] ...
- cogs2109 [NOIP2015] 运输计划
cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...
- bzoj 4326: NOIP2015 运输计划
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...
- [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划
[BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划 试题描述 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− ...
- [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组
[NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...
- AC日记——[NOIP2015]运输计划 cogs 2109
[NOIP2015] 运输计划 思路: 树剖+二分: 代码: #include <cstdio> #include <cstring> #include <iostrea ...
- 题解 [NOIP2015]运输计划
题解 [NOIP2015]运输计划 题面 解析 首先肯定是要求出每条路径的长度. 这个用节点到根的前缀和就行了(一开始脑抽写了个线段树...) 然后有一个显然的类似贪心的想法, 就是你改造的边肯定在最 ...
随机推荐
- ElementUI的el-table的多选的取消选择和筛选的取消所有过滤器之ref冲突问题
写此文的缘由:现如今,网络上,没有同下的解释形式(或者在外网,所以我没找到,或者大佬觉得太简单所以不屑解释).然而,我认为这是对VUE+ElementUI的底层框架的理解深入化问题.(为什么要深入理解 ...
- Navicat Premium怎么设置字段的唯一性(UNIQUE)?
参考链接:https://blog.csdn.net/Song_JiangTao/article/details/82192189 1.打开你想要设计的表 这里写图片描述2.清楚你想要设计哪个字段为唯 ...
- 牛客网——剑指offer(跳台阶以及变态跳台阶_java实现)
首先说一个剪枝的概念: 剪枝出现在递归和类递归程序里,因为递归操作用图来表示就是一棵树,树有很多分叉,如果不作处理,就有很多重复分叉,会降低效率,如果能把这些分叉先行记录下来,就可以大大提升效率——这 ...
- shell变量内字符替换和变量字符修改
vi test.sh a= #将${a}里的第一个123替换为321 b=${a//}; echo "echo variable a" echo $a echo "ech ...
- RN开发-windows环境搭建
1.安装jdk,sdk,C++运行环境(cygwin,Windows SDK,mingw),node.js和git 2.设置全局使用指定的镜像 打开git-cmd.exe ...
- app点击底部菜单切换标题
<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <meta name=& ...
- 使用 C++11 编写可复用多线程任务池
类的功能 Task (任务基类) 该类主要实现一个任务类 virtual int doWork() = 0; TaskQueue (任务队列) 该类主要针对任务的存储.删除.撤回等状态做管理 Thre ...
- hashlib加密模块_python
一.hashlib模块 1.功能 主要用于字符串加密 2.常用方法 md5()/sha1():创建一个md5或者sha1加密模式的hash对象update(arg):用字符串参数来更新hash对象,如 ...
- 题解【洛谷P3478】[POI2008]STA-Station
题面 设\(dp_i\)表示以\(i\)为根节点时所有节点的深度之和. 首先以 \(1\) 为根求出所有点深度之和\(dp_1\),并预处理每个点的子树大小. 设 \(v\) 是 \(u\) 的孩子, ...
- [USACO19OPEN]I Would Walk 500 Miles 贪心
题目 洛谷P5425(点击可跳转) 题目描述 Farmer John想要将他的编号为 \(1 \ldots N\)的 N N 头奶牛( \(N \leq 7500\) )分为非空的 \(K\) 组( ...