[NOIP2015]运输计划

链接

luogu

好久没写博客了,水一篇波。

思路1 暴力数据结构

枚举最长链的边,删除后代价为(最长链-边权,不经过这条边的链)的最大值。

不经过某条边的最大值要用线段树维护补集。

复杂度\(O(nlog^2n)\)

思路2 二分树上差分

二分答案,删除的边为\(>mid\)的链的交集。

用树上查分维护交集。

最后在交集中找个最大的边删除就好了。

复杂度\(O(nlogn)\)

总的

思路2,复杂度小,好写,简单,细节少。

思路1,复杂度高,码量大,细节多,并不是呢么好想。

所以并不是很建议写第一种。

但他靠着树剖的小常数跑过了树上差分(至少我是这样,1.9s->1.2s)。

代码1

#include <bits/stdc++.h>
using namespace std;
const int _=5e5+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,ans,u[_],v[_],dsr[_],w[_];
struct node {
int v,nxt,q,w;
}e[_<<1];
int head[_],tot;
void add(int u,int v,int q) {
e[++tot].v=v;
e[tot].q=q;
e[tot].nxt=head[u];
head[u]=tot;
}
int f[_],dep[_],siz[_],son[_],top[_],idx[_],dis[_],nb[_],cnt;
void dfs1(int u,int fa) {
dep[u]=dep[fa]+1;
f[u]=fa;
siz[u]=1;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
w[v]=e[i].q;
dis[v]=dis[u]+e[i].q;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v]) son[u]=v;
}
}
void dfs2(int u,int topf) {
top[u]=topf;
idx[u]=++cnt;
nb[cnt]=u;
if(!son[u]) return;
dfs2(son[u],topf);
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(!idx[v]) dfs2(v,v);
}
}
namespace seg_tree {
#define ls rt<<1
#define rs rt<<1|1
int ma[_<<2],lazy[_];
void tag(int rt,int val) {ma[rt]=max(ma[rt],val);lazy[rt]=max(lazy[rt],val);}
void pushdown(int rt) {tag(ls,lazy[rt]);tag(rs,lazy[rt]);}
void modify(int L,int R,int val,int l,int r,int rt) {
if(L>R) return;
if(L<=l&&r<=R) return tag(rt,val);
int mid=(l+r)>>1;
pushdown(rt);
if(L<=mid) modify(L,R,val,l,mid,ls);
if(R>mid) modify(L,R,val,mid+1,r,rs);
ma[rt]=max(ma[ls],ma[rs]);
}
void dfs(int l,int r,int rt) {
if(l==r) return void(dsr[nb[l]]=ma[rt]);
int mid=(l+r)>>1;
pushdown(rt);
if(l<=mid) dfs(l,mid,ls);
if(r>mid) dfs(mid+1,r,rs);
}
}
int lca(int x,int y) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=f[top[x]];
} return dep[x]<dep[y]?x:y;
}
void QQ(int x,int y,int val) {
int las=n;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
seg_tree::modify(idx[x]+1,las,val,1,n,1);
las=idx[top[x]]-1;
x=f[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
seg_tree::modify(idx[x]+1,las,val,1,n,1);
seg_tree::modify(1,idx[y],val,1,n,1);
}
int main() {
n=read(),m=read();
for(int i=1,x,y,q;i<n;++i) {
x=read(),y=read(),q=read();
add(x,y,q),add(y,x,q);
}
for(int i=1;i<=m;++i) {
u[i]=read(),v[i]=read();
if(u[i]==v[i]) m--,i--;
}
dfs1(1,0),dfs2(1,1);
int id=0,ma=0;
for(int i=1;i<=m;++i) {
int val=dis[u[i]]+dis[v[i]]-2*dis[lca(u[i],v[i])];
QQ(u[i],v[i],val);
if(ma<val) id=i,ma=val;
}
if(!id) return printf("0\n"),0;
seg_tree::dfs(1,n,1);
int x=u[id],y=v[id],ans=0x3f3f3f3f;
while(x!=y) {
if(dep[x]<dep[y]) swap(x,y);
ans=min(ans,max(dsr[x],ma-w[x]));
x=f[x];
}
cout<<ans<<"\n";
return 0;
}

代码2

#include <bits/stdc++.h>
using namespace std;
const int _=5e5+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,ans,u[_],v[_],LCA[_],len[_],the_biggest,w[_];
struct node {
int v,nxt,q;
}e[_<<1];
int head[_],tot;
void add(int u,int v,int q) {
e[++tot].v=v;
e[tot].q=q;
e[tot].nxt=head[u];
head[u]=tot;
}
int f[_],dep[_],siz[_],son[_],dis[_],top[_],cnt;
void dfs1(int u,int fa) {
dep[u]=dep[fa]+1,f[u]=fa,siz[u]=1;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
w[v]=e[i].q;
dis[v]=dis[u]+e[i].q;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v]) son[u]=v;
}
}
void dfs2(int u,int topf) {
top[u]=topf;
if(!son[u]) return;
dfs2(son[u],topf);
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(!top[v]) dfs2(v,v);
}
}
int lca(int x,int y) {
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=f[top[x]];
} return dep[x]<dep[y]?x:y;
}
int dsr[_],js;
void dfs(int u,int fa) {
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(v==fa) continue;
dfs(v,u);
dsr[u]+=dsr[v];
}
}
bool check(int mid) {
js=0;
for(int i=0;i<=n;++i) dsr[i]=0;
for(int i=1;i<=m;++i) {
if(len[i]<=mid) continue;
dsr[LCA[i]]-=2;
dsr[u[i]]++;
dsr[v[i]]++;
++js;
}
dfs(1,0);
int ma=0x3f3f3f3f;
for(int i=1;i<=n;++i)
if(dsr[i]==js) ma=min(ma,the_biggest-w[i]);
return ma<=mid;
}
int main() {
n=read(),m=read();
for(int i=1,x,y,q;i<n;++i) {
x=read(),y=read(),q=read();
add(x,y,q),add(y,x,q);
}
dfs1(1,0),dfs2(1,1);
for(int i=1;i<=m;++i) {
u[i]=read(),v[i]=read(),LCA[i]=lca(u[i],v[i]);
len[i]=dis[u[i]]+dis[v[i]]-2*dis[LCA[i]];
the_biggest=max(the_biggest,len[i]);
}
int l=0,r=the_biggest,ans=0;
while(l<=r) {
int mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
} cout<<ans<<"\n";
return 0;
}

[NOIP2015]运输计划 线段树or差分二分的更多相关文章

  1. bzoj 4326: NOIP2015 运输计划【树链剖分+二分+树上差分】

    常数巨大,lg上开o2才能A 首先预处理出运输计划的长度len和lca,然后二分一个长度w,对于长度大于w的运输计划,在树上差分(d[u]+1,d[v]+1,d[lca]-2),然后dfs,找出所有覆 ...

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

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

  3. [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组

    [NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...

  4. BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)

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

  5. NOIP2015 运输计划(二分+LCA+差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 308  Solved: 208[Submit][Status] ...

  6. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

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

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

  8. LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*

    LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...

  9. BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 1388  Solved: 860 [Submit][Stat ...

随机推荐

  1. Unreal Engine 4 系列教程 Part 6:动画教程

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  2. ideal 切换git和svn

    原文地址:https://blog.csdn.net/lixld/article/details/98851427 intellij ideal gi和svn切换: 之前项目是svn的,新的项目用了g ...

  3. jwt入门

    JWT(JSON Web Token)是一个非常轻巧的规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息,通常使用在HTTP通信过程中进行身份认证. 我们知道,HTTP通信是无状态的 ...

  4. Knative 实践:从源代码到服务的自动化部署

    通过之前的文章,相信大家已经熟悉了 Serving.Eventing 以及 Tekton.那么在实际使用中,我们往往会遇到一些复杂的场景,这时候就需要各个组件之间进行协作处理.例如我们提交源代码之后是 ...

  5. 服务器部署Laravel

    安装lnmp环境 参考:简书 - Centos 7 下安装LNMP官方最新版 安装redis 参考:简书 - Centos 7下使用yum安装redis 安装nodejs npm nodejs分8.x ...

  6. Mvc 入门及基础了解

    用于表示一种软件架构模式.它把软件系统分为三个基本部分 _模型(Model), _视图(View) _和控制器(Controller). 其中主要代码是 路由 配置默认的路径: 默认配置 是 Home ...

  7. 微信测试号:config:invalid url domain

    今天调试微信分享的时候,配置参数时一直提示config:invalid url domain,网上找了一下,都说是appId和域名没有绑定.仔细看了下,有绑定没错.又猜测是不是二级域名的问题,因为是测 ...

  8. rhel安装输入法

    # yum install "@Chinese Support" 安装完成后,设置输入法: System -> Preferences -> Input Method

  9. Violet音乐社区 - 总结报告

    目录 一.项目概述 1.1 项目背景 1.2 编写目的 1.3 项目文档 1.4 项目源码 1.5 项目成果 二.个人工作总结 1.1 工作概览 1.1.1 作为项目组组长 1.1.2 作为项目组成员 ...

  10. Scrum 冲刺第二篇

    我们是这次稳了队,队员分别是温治乾.莫少政.黄思扬.余泽端.江海灵 一.会议 1.1  26号站立式会议照片: 1.2  昨天已完成的事情 团队成员 任务内容 黄思扬 Web 端首页.内容管理页开发. ...