bzoj 4326 运输计划 (树链剖分 + 树上差分 + 二分)
来源:互联网 发布:网络小胖的电视 编辑:程序博客网 时间:2024/09/21 09:28
不想贴题面系列……
这道题就是先二分一个答案,然后check,如果路线的总长度比二分的答案大,就把它们拎出来进行树上差分(求它们所有路线都经过的边),然后把这条边的权值减掉(贪心),反复check即可。
#include <bits/stdc++.h>using namespace std;const int N = 300010;int n, m;struct E { int v, w, next;} e[N << 1];int num = 0, head[N << 1];void add(int u, int v, int w) { e[++ num].v = v; e[num].w = w; e[num].next = head[u]; head[u] = num;}struct Node { int s, t, len, lca;} car[N];int fa[N], son[N], siz[N], dep[N], dis[N], top[N];void dfs1(int u, int f, int d) { siz[u] = 1; fa[u] = f; dep[u] = d; for(int i = head[u]; i; i = e[i].next) { int v = e[i].v; if(v == f) continue; dis[v] = dis[u] + e[i].w; dfs1(v, u, d + 1); siz[u] += siz[v]; if(siz[son[u]] < siz[v]) son[u] = v; }}void dfs2(int u, int tp) { top[u] = tp; if(! son[u]) return ; dfs2(son[u], tp); for(int i = head[u]; i; i = e[i].next) { int v = e[i].v; if(v == fa[u] || v == son[u]) continue; dfs2(v, v); }}int getlca(int u, int v) { int fu = top[u], fv = top[v]; while(fu != fv) { if(dep[fu] < dep[fv]) swap(fu, fv), swap(u, v); u = fa[fu], fu = top[u]; } if(dep[u] > dep[v]) swap(u, v); return u;}int tot, delta, mmax, flag[N];void dfs(int u, int W) { for(int i = head[u]; i; i = e[i].next) { int v = e[i].v; if(v == fa[u]) continue ; dfs(v, e[i].w); flag[u] += flag[v]; } if(flag[u] == tot) delta = max(W, delta);}bool check(int mid) { tot = delta = mmax = 0; memset(flag, 0, sizeof(flag)); for(register int i = 1; i <= m; ++ i) if(car[i].len > mid) { ++ tot; mmax = max(mmax, car[i].len - mid); flag[car[i].s] ++, flag[car[i].t] ++, flag[car[i].lca] -= 2; } dfs(1, 0); if(mmax - delta > 0) return 0; return 1;}int main() { scanf("%d %d", &n, &m); for(register int i = 1; i < n; ++ i) { int u, v, w; scanf("%d %d %d", &u, &v, &w); add(u, v, w); add(v, u, w); } dfs1(1, 0, 1); dfs2(1, 1); int l = 0, r = 0; for(register int i = 1; i <= m; i ++) { scanf("%d %d", &car[i].s, &car[i].t); car[i].lca = getlca(car[i].s, car[i].t); car[i].len = dis[car[i].s] + dis[car[i].t] - 2 * dis[car[i].lca]; r = max(r, car[i].len); } while(l < r) { int mid = (l + r) >> 1; if(check(mid)) r = mid; else l = mid + 1; } printf("%d\n", l); return 0;}
阅读全文
0 0
- bzoj 4326 运输计划 (树链剖分 + 树上差分 + 二分)
- 【BZOJ】4326 NOIP2015 运输计划 二分+LCA+树上差分
- BZOJ 4326: NOIP2015 运输计划 二分答案 树上差分
- bzoj 4326: NOIP2015 运输计划 树链剖分+二分+差分数组
- 【BZOJ 4326】运输计划【树链剖分+差分+二分答案】
- [BZOJ]4326: NOIP2015 运输计划 二分+树链剖分+差分
- BZOJ[4326][NOIP2015]运输计划 二分答案+树链剖分+差分
- [BZOJ4326][NOIP2015]运输计划(二分答案+树上差分)
- [二分+差分]BZOJ 4326——NOIP2015 运输计划
- BZOJ 4326: NOIP2015 运输计划【LCA】【二分】【差分】
- NOIP2015 运输计划 (树链剖分,LCA,树上差分)
- LuoguP2680/UOJ150[NOIP2015] 运输计划 解题报告【二分答案+树上操作(LCA)+树上差分】
- 【NOIP2015】运输计划 {二分答案+倍增+树上差分}
- NOIP2015 运输计划 二分答案+Tarjan LCA+树上差分
- luogu #2680 运输计划(二分答案+树上差分)(noip2015)
- [BZOJ4326][NOIP2015]运输计划(二分+dfs序+树上差分)
- [BZOJ4326][NOIP2015]运输计划(二分+dfs序+树上差分)
- NOIP 2015 Day2 T3 运输计划(二分+dfs序+树上差分+倍增LCA)
- JAVA环境安装文档
- React Native 电商五星好评封装
- hbase-shell过滤
- 简单Android 6.0权限处理
- 就鹿晗宣布恋情导致微博宕机事件浅谈大型网站高可用性架构
- bzoj 4326 运输计划 (树链剖分 + 树上差分 + 二分)
- 第八周-项目1
- 优先队列的简单用法
- 第九周项目一—二叉树算法库
- 点击图片跳转到web页面
- [PAT]1027. Colors in Mars (20)@Java实现
- Android布局中onClick属性
- Docker学习(2)构建并测试Web应用程序
- MySQL 源码安装