UOJ 150 [NOIP2015]运输计划
来源:互联网 发布:怎么查淘宝单号码查询 编辑:程序博客网 时间:2024/06/05 04:35
二分+树链剖分求LCA+差分
要求最远的值最小,于是我们可以考虑二分答案。
对于每一个二分出来的lim,我们只需要判断所有路径(指运输计划里面所有的路径)中长度大于lim的所有路径是否存在一条公共边,使得最长路径减去它可以小于等于lim(如果最长的可以,那么短的也肯定可以)
那么怎么求这条边?我刚开始的想法是树剖+线段树,对每一条超过lim的路径上的边的都记+1,然后暴力枚举边来找公共边。但是这样是
实际上可以根本不线段树,维护一个树上差分数组f即可,值也是照样加。。。预处理所有LCA,复杂度就是
#include<cstdio>#include<cstring>#include<algorithm>#define N 300005#define reg registerusing namespace std;struct edge{int next,to,val;}e[N<<1];int ecnt;int n, m, last[N], fa[N], dep[N], siz[N], top[N], son[N], u[N], v[N], d[N], dis[N], Lca[N], f[N], mxlen, mx, tot, b[N];int in(){ reg int r=0; reg char c=getchar(); while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9')r=r*10+c-'0',c=getchar(); return r;}void addedge(int a, int b, int c){ e[++ecnt]=(edge){last[a],b,c}; last[a]=ecnt;}void dfs1(int x){ dep[x]=dep[fa[x]]+1; siz[x]=1; for(int i = last[x]; i; i=e[i].next) { int y=e[i].to; if(y==fa[x])continue; fa[y]=x; dis[y]=dis[x]+e[i].val; dfs1(y); siz[x]+=siz[y]; if(siz[y]>siz[son[x]]) son[x]=y; }}void dfs2(int x){ if(son[fa[x]]==x)top[x]=top[fa[x]]; else top[x]=x; for(int i = last[x]; i; i=e[i].next) { int y=e[i].to; if(y!=fa[x]) dfs2(y); }}int lca(int a, int b){ while(top[a]!=top[b]) { if(dep[top[a]]>dep[top[b]]) a=fa[top[a]]; else b=fa[top[b]]; } return dep[a]>dep[b]?b:a;}void make(int i){ f[u[i]]++; f[v[i]]++; f[Lca[i]]-=2;}void find(int x){ b[x]=f[x]; for(int i = last[x]; i; i=e[i].next) { int y=e[i].to; if(y==fa[x])continue; find(y); b[x]+=b[y]; if(b[y]==tot) mx=max(mx,e[i].val); }}bool check(int lim){ tot=0; memset(f,0,sizeof(f)); for(int i = 1; i <= m; i++) if(d[i]>lim) { ++tot; make(i); } mx=0; find(1); return mxlen-mx<=lim;}int main(){ n=in(), m=in(); for(int i = 1; i < n; i++) { int a=in(), b=in(), t=in(); addedge(a,b,t); addedge(b,a,t); } dfs1(1); dfs2(1); for(int i = 1; i <= m; i++) { u[i]=in(), v[i]=in(); d[i]=dis[u[i]]+dis[v[i]]-2*dis[Lca[i]=lca(u[i],v[i])]; mxlen=max(mxlen,d[i]); } int l = max(0,mxlen-1000), r = mxlen; while(l<r) { int mid=(l+r)>>1; if(check(mid))r=mid; else l=mid+1; } printf("%d\n",l);}
1 0
- UOJ 150 [NOIP2015]运输计划
- 【uoj#150】【NOIP2015】运输计划 树上前缀和+lca+二分+拓扑排序+特别的卡常数技巧
- NOIP 2015 && UOJ#150 运输计划
- 【NOIP2015】【BZOJ4326】运输计划
- [bzoj4326][NOIP2015]运输计划
- NOIP2015 运输计划
- NOIP2015 day2t3 运输计划
- NOIP2015运输计划 题解
- noip2015 运输计划
- codevs4632: [NOIP2015]运输计划
- NOIP2015 D2T3运输计划
- noip2015运输计划
- 【NOIP2015】Day2T3 运输计划
- NOIP2015运输计划
- [NOIP2015]运输计划
- NOIP2015 运输计划
- NOIP2015 day2t3 运输计划
- 4326: NOIP2015 运输计划
- Java反射机制
- POJ 1742 Coins 混合三种背包问题
- Fragment 布局
- 手机互连(Mobile Connect)简介
- 安全卫士随记
- UOJ 150 [NOIP2015]运输计划
- 2016.10.5总结:
- Go、Nginx、Php、Nodejs谁能胜出紫禁之巅
- 旅行_纪中1281_dp
- 欢迎使用CSDN-markdown编辑器
- 通过经纬度计算距离
- poj 3126 Prime Path(BFS)
- JAVA—GUI(图形用户界面)编程
- 泔水()