[二分+LCA+差分]【NOIP2015D2T3】运输计划 题解
来源:互联网 发布:淘宝代购lv是真的吗 编辑:程序博客网 时间:2024/05/29 15:20
传送门:
洛谷:https://daniu.luogu.org/problemnew/show/2680#sub
(链接给的是大牛分站的,主站上T了一个点,大牛分站A了,“高性能”,卡常数)
UOJ:http://uoj.ac/problem/150
题目分析
给出一棵
解题分析
最大中求最小,套路想到二分。二分答案ans,预先LCA求出每个任务所需时间,判断出有多少个运输计划超出了ans。
因为题目中要求只能选一条边,所以我们肯定要求这条边在所有超出ans的运输计划,而且这条边肯定尽可能地大。可以用差分来找出有没有这条边。先刷出所有超出ans的运输计划个数k和最大的差距tem,然后sum数组,对于每一个计划
注意每个任务的LCA值建议存储起来节省空间。
复杂度:
时间:
空间:
#include<cstdio>#include<cstring>#include<algorithm>#define maxn 300005#define maxe 600005using namespace std;int n,m,tot,len,ans,s[maxn],t[maxn],dis[maxn],cst[maxn],son[maxe],nxt[maxe],w[maxe],lnk[maxn],dep[maxn],fa[maxn][20],sum[maxn],v[maxn],la[maxn];inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void readi(int &x){ x=0; char ch=nc(); while ('0'>ch||ch>'9') ch=nc(); while ('0'<=ch&&ch<='9') {x=x*10+ch-'0'; ch=nc();}}void _add(int x,int y,int z){ son[++tot]=y; w[tot]=z; nxt[tot]=lnk[x]; lnk[x]=tot;}void _dfs(int x,int dad){ for (int j=lnk[x];j;j=nxt[j]) if (son[j]!=dad){ dep[son[j]]=dep[x]+1; dis[son[j]]=dis[x]+w[j]; _dfs(son[j],x); fa[son[j]][0]=x; v[son[j]]=w[j]; }}void _init(){ freopen("transport.in","r",stdin); freopen("transport.out","w",stdout); readi(n); readi(m); dis[1]=dep[0]=0; for (int i=1,x,y,z;i<n;i++){ readi(x); readi(y); readi(z); _add(x,y,z); _add(y,x,z); } dep[1]=1;_dfs(1,0); len=19; for (int j=1;j<=len;j++) for (int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1];}int _LCA(int x,int y){ if (dep[x]<dep[y]) swap(x,y); for (int j=len;j>=0&&dep[x]>dep[y];j--) if (dep[fa[x][j]]>=dep[y]) x=fa[x][j]; if (x==y) return x; for (int j=len;j>=0;j--) if (fa[x][j]!=fa[y][j]) {x=fa[x][j]; y=fa[y][j];} return fa[x][0];}void dfsc(int x,int dad){ for (int j=lnk[x];j;j=nxt[j]) if (son[j]!=dad) {dfsc(son[j],x); sum[x]+=sum[son[j]];}}bool _check(int x){ int tem=0,k=0; memset(sum,0,sizeof(sum)); for (int i=1;i<=m;i++) if (cst[i]>x){ sum[s[i]]++; sum[t[i]]++; sum[la[i]]-=2; k++; tem=max(tem,cst[i]-x); } if (tem==0) return 1; dfsc(1,0); for (int i=2;i<=n;i++) if (sum[i]==k&&v[i]>=tem) return 1; return 0;}void _solve(){ int L=0,R=0,mid; for (int i=1;i<=m;i++){ readi(s[i]); readi(t[i]); la[i]=_LCA(s[i],t[i]); cst[i]=dis[s[i]]+dis[t[i]]-(dis[la[i]]<<1); R=max(R,cst[i]); } while (L<=R){ mid=(R-L)/2+L; if (_check(mid)) R=mid-1; else L=mid+1; } printf("%d",L);}int main(){ _init(); _solve(); return 0;}
阅读全文
0 0
- [二分+LCA+差分]【NOIP2015D2T3】运输计划 题解
- 【二分+LCA+差分】BZOJ4326(NOIP2015)[运输计划]题解
- 【NOIP2015】【bzoj4326】运输计划 LCA+差分+二分答案
- Noip2015 运输计划 【二分答案】【差分】【LCA】
- BZOJ4326(NOIP2015)运输计划--二分+LCA+差分
- 【BZOJ】4326 NOIP2015 运输计划 二分+LCA+树上差分
- BZOJ 4326: NOIP2015 运输计划【LCA】【二分】【差分】
- NOIP2015 运输计划 二分答案+Tarjan LCA+树上差分
- [bzoj4326][NOIP2015] 运输计划 差分+LCA
- NOIP2015 运输计划 树链剖分 差分 二分
- [NOIP2015]运输计划 树链剖分 二分 差分
- 洛谷 2680[NOIP2015] 运输计划 二分+lca+树上差分+dfs序
- LCA+二分+树上差分——Luogu2680 [NOIP2015]运输计划
- 【二分+LCA差分乱搞】BZOJ4326(UOJ150) NOIP2015 运输计划
- NOIP 2015 Day2 T3 运输计划(二分+dfs序+树上差分+倍增LCA)
- <考试题> codevs 5440 运输计划 (二分+lca+dfs序+树上差分)
- luogu2680【2015提高】运输计划(二分答案+lca+树上差分前缀和)
- LuoguP2680/UOJ150[NOIP2015] 运输计划 解题报告【二分答案+树上操作(LCA)+树上差分】
- 【Codeforces875B】Sorting the Coins
- typescript
- 工业相机50问
- Java
- markdown发生HTML渲染组件出错的解决方案
- [二分+LCA+差分]【NOIP2015D2T3】运输计划 题解
- C语言学习系列1-helloworld示例
- Effect(七)—— BuffEffect
- leetcode算法笔记1
- oracle之 Oracle归档日志管理
- linux vsftpd 升级步骤
- Java IO流的介绍
- java打印3位的水仙花数
- 23. Merge k Sorted Lists