洛谷 2680 运输计划
来源:互联网 发布:2017通货膨胀 知乎 编辑:程序博客网 时间:2024/06/04 23:52
//二分+倍增LCA+树上前缀和//尽力缩小二分范围,能多拿分就多拿分//掌握树上前缀和的初始化和区间修改 //读入优化//二分答案,然后找出超出mid的计划,记录他们的公共重边,这里用树上前缀和找前缀和exc==超出计划数 的最大的边,删掉后再判断是否<=mid。 #include<bits/stdc++.h>using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 300010;int n, m, tot, maxw, maxl;int st[maxn*2], dep[maxn], f[maxn][23], dis[maxn], from[maxn], lca[maxn], s[maxn], e[maxn], t[maxn];int len[maxn];struct node{ int v, w, nxt;} edge[2*maxn];inline int read(){ int num = 0; char c; while((c = getchar()) == ' ' || c == '\n' || c == '\r'); num = c - '0'; while(isdigit(c = getchar())) num = num*10 + c - '0'; return num;}inline void in(int x, int y, int z){ edge[++tot].v = y; edge[tot].w = z; edge[tot].nxt = st[x]; st[x] = tot;}///inline void BuildT(int now){ dep[now] = dep[f[now][0]] + 1; for(int i = 1; i <= 21; i++){ if(dep[now] < (1<<i)) break;//剪枝 f[now][i] = f[f[now][i-1]][i-1]; } for(int i = st[now]; i; i = edge[i].nxt){ int to = edge[i].v; if(to != f[now][0]){ f[to][0] = now; dis[to] = dis[now] + edge[i].w; from[to] = i; BuildT(to); } }}///inline int LCA(int x, int y){ if(dep[x] < dep[y]) swap(x, y); int delta = dep[x] - dep[y]; for(int i = 0; i <= 21; i++) if(delta & (1<<i)) x = f[x][i];//注意这个条件 if(x == y) return x; for(int i = 21; i >= 0; i--) if(f[x][i] != f[y][i]){ x = f[x][i]; y = f[y][i]; } return f[x][0];}///inline int getLen(int num, int p, int q){ return dis[p] + dis[q] - (dis[lca[num] = LCA(p, q)] << 1);}///inline void change(int num, int turn){//区间修改树上前缀和 t[s[num]] += turn; t[e[num]] += turn; t[lca[num]] -= (turn << 1);}///inline int getMax(int now, int cnt){ int exc = t[now];//前缀和累加器,记录有多少计划经过这条边 for(int i = st[now]; i; i = edge[i].nxt){ int to = edge[i].v; if(to == f[now][0]) continue; exc += getMax(to, cnt); } if(exc == cnt) maxw = max(maxw, edge[from[now]].w);//找到公共重边 return exc;}inline bool check(int now){ memset(t, 0, sizeof(t)); int cnt = 0; for(int i = 1; i <= m; i++) if(len[i] > now){ cnt++; change(i, 1); } if(!cnt) return 1; maxw = 0; getMax(1, cnt); /*for(int i = 1; i <= n; i++) printf("%d ", t[i]);*/ //printf("%d\n", maxw); return maxl - maxw <= now;}int main(){ int maxz = 0; n = read(); m = read(); for(int i = 1, x, y, z; i < n; i++){ x = read(); y = read(); z = read(); maxz = max(maxz, z); in(x, y, z); in(y, x, z); } f[1][0] = 0; BuildT(1); maxl = 0; for(int i = 1; i <= m; i++){ s[i] = read(); e[i] = read(); len[i] = getLen(i, s[i], e[i]); maxl = max(maxl, len[i]); } int l = maxl - maxz, r = maxl + 1, mid; while(l < r){ mid = l+r >> 1; if(check(mid)) r = mid; else l = mid + 1;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } /*for(int i = 1; i <= m; i++) printf("%d ", lca[i]);*/ printf("%d\n", l); return 0;}
阅读全文
0 0
- 洛谷 2680 运输计划
- 【NOIP2015】洛谷2680 运输计划【解法一】
- 【NOIP2015】洛谷2680 运输计划【解法二】
- NOIP2015运输计划(洛谷2680)
- 洛谷 P2680 运输计划
- 洛谷 P2680 运输计划
- 洛谷P2680 运输计划
- 【洛谷2680】【BZOJ 4326】运输计划 lca+差分
- 运输计划
- 运输计划
- 运输计划
- 运输计划
- [luogu-2680]noip2015day2-T3 运输计划 题解
- 洛谷 2680[NOIP2015] 运输计划 二分+lca+树上差分+dfs序
- 【NOIP2015】【BZOJ4326】运输计划
- [bzoj4326][NOIP2015]运输计划
- NOIP2015 运输计划
- NOIP2015 day2t3 运输计划
- android开发设置带加载进度网页的WebViewActivity
- 欢迎使用CSDN-markdown编辑器
- 2017/08/24 线程安全
- 学习Opencv2.4.9(四)---SVM支持向量机
- mr2 wordcount 源码解析
- 洛谷 2680 运输计划
- React Native高度自增长的TextInput组件
- 机器学习-学习笔记 学习总结归纳(第十一周)
- 计算机网络,操作系统,数据结构,算法设计,计算机组成原理,数据库,概率论 零散知识库
- python webpy 安装
- 转原始串转义串的网页小工具
- 从github上clone代码
- 并发网
- java序列化实现RMI