BZOJ2051——A Problem For Fun
0、题意:给出一个N个结点的树,每条边有一个正整数权值,定义两个结点的距离为连接这两个结点路径上边权的和。对于每个结点i,它到其他N-1个结点都有一个距离,将这些距离从小到大排序,输出第K个距离。
1、分析:这个题我问了一下Claris,然后理解了,我们存下logn个分支结构,然后我们在分治结构中二分就好了QAQ
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 2000010
inline int read(){
char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
struct Edge{
int u, v, w, next;
} G[M];
int head[M], ed;
int size, f[M], son[M], ok[M];
int cnt, now;
int V[2][M], g[M], nxt[M], W[M], ED;
int rl[M], rr[M], el[M], er[M];
int q[M], tot, n, m;
inline void add(int u, int v, int w){
G[++ ed] = (Edge){u, v, w, head[u]};
head[u] = ed;
}
inline void ADD(int u, int v1, int v2, int w){
V[0][++ ED] = v1;
V[1][ED] = v2;
nxt[ED] = g[u];
g[u] = ED;
W[ED] = w;
}
inline void FindRoot(int x, int fa){
son[x] = 1; f[x] = 0;
for(int i = head[x]; i != -1; i = G[i].next) if(G[i].v != fa && !ok[i]){
FindRoot(G[i].v, x);
son[x] += son[G[i].v];
if(son[G[i].v] > f[x]) f[x] = son[G[i].v];
}
if(size - son[x] > f[x]) f[x] = size - son[x];
if(f[x] < f[now]) now = x;
}
inline void dfs(int x, int fa, int dis){
q[++ tot] = dis;
for(int i = head[x]; i != -1; i = G[i].next) if(G[i].v != fa && !ok[i]){
dfs(G[i].v, x, dis + G[i].w);
}
}
inline void dfs2(int x, int fa, int dis){
ADD(x, now, cnt, dis);
q[++ tot] = dis;
for(int i = head[x]; i != -1; i = G[i].next) if(G[i].v != fa && !ok[i]){
dfs2(G[i].v, x, dis + G[i].w);
}
}
inline void solve(int x){
q[rl[x] = ++ tot] = 0;
for(int i = head[x]; i != -1; i = G[i].next) if(!ok[i]){
dfs(G[i].v, x, G[i].w);
}
sort(q + rl[x], q + tot + 1);
rr[x] = tot;
for(int i = head[x]; i != -1; i = G[i].next) if(!ok[i]){
el[++ cnt] = tot + 1;
dfs2(G[i].v, x, G[i].w);
sort(q + el[cnt], q + tot + 1);
er[cnt] = tot;
}
for(int i = head[x]; i != -1; i = G[i].next) if(!ok[i]){
ok[i ^ 1] = 1;
f[0] = size = son[G[i].v];
FindRoot(G[i].v, now = 0);
solve(now);
}
}
inline int ask(int L, int r, int x){
int l = L, t = l - 1, mid;
while(l <= r){
mid = (l + r) / 2;
if(q[mid] <= x) l = (t = mid) + 1;
else r = mid - 1;
}
return t - L + 1;
}
inline int query(int x, int k){
int t = ask(rl[x], rr[x], k) - 1;
for(int i = g[x]; i != -1; i = nxt[i]) t += ask(rl[V[0][i]], rr[V[0][i]], k - W[i]) - ask(el[V[1][i]], er[V[1][i]], k - W[i]);
return t;
}
inline int getans(int x){
int l = 1, r = 10000 * (n - 1), mid;
while(l < r){
mid = (l + r) / 2;
if(query(x, mid) < m) l = mid + 1;
else r = mid;
}
return l;
}
int main(){
n = read(), m = read();
memset(head, -1, sizeof(head)); ED = ed = -1;
memset(g, -1, sizeof(g));
for(int i = 1; i < n; i ++){
int u = read(), v = read(), w = read();
add(u, v, w); add(v, u, w);
}
size = f[0] = n;
FindRoot(1, now = 0);
solve(now);
for(int i = 1; i <= n; i ++) printf("%d\n", getans(i));
return 0;
}
BZOJ2051——A Problem For Fun的更多相关文章
- [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树
[BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树 题目大意: 给出一个\(n(n\le10^5)\)个结点的树,每条边有 ...
- BZOJ2051 : A Problem For Fun
树的点分治,将点分治的过程记录下来,每一个分治结构按到分治中心的距离维护所有点. 对于一个点二分答案,然后在$O(\log n)$个分治结构中二分查找,时间复杂度$O(n\log^3n)$. #inc ...
- 1199 Problem B: 大小关系
求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...
- No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.
Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...
- C - NP-Hard Problem(二分图判定-染色法)
C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:262144 ...
- Time Consume Problem
I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...
- Programming Contest Problem Types
Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...
- hdu1032 Train Problem II (卡特兰数)
题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能. (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...
- BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 4032 Solved: 1817[Submit] ...
随机推荐
- cobbler工作流分析
官网 http://cobbler.github.io/ 介绍 Cobbler是一个快速网络安装linux的服务,而且在经过调整也可以支持网络安装windows.该工具使用python开发,小巧轻便, ...
- BZOJ2124: 等差子序列
题意:给一个 1 到 N 的排列{Ai},询问是否存在 1<=p1<p2<p3<p4<p5<…<pLen<=N(Len>=3),使得 Ap1,Ap ...
- 【原】React操作表单
最近的项目中开发中都是用react,其中有用到react去操纵表单.然后自己就在每个表单元素中添加 ref, 然后再像jquery操作dom一样去操纵这个ref, 代码如下: 首先我在每个表单元素那 ...
- nginx查看安装了哪些模块
查看安装了哪些模块命令: [root@RG-PowerCache-X xcache]# nginx/sbin/nginx -Vnginx version: nginx/1.2.3built by gc ...
- telnet连接ip
win7 telnet命令无法开启的解决方案(不是内部命令或外部命令) 出处:西西整理 作者:西西 日期:2012-12-21 14:22:06 [大 中 小] 评论: 0 | 我要发表看法 如果你想 ...
- MySQL学习笔记——多表连接和子查询
多表连接查询 # 返回的是两张表的乘积 SELECT * FROM tb_emp,tb_dept SELECT COUNT(*) FROM tb_emp,tb_dept # 标准写法,每个数据库都能这 ...
- HTML 通知公告练习
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Vim以及Terminal 配色方案---"Solarized"配色
linux用户给vim 以及terminal的配色方案---Solarized配色 官网地址:http://ethanschoonover.com/solarized 看这配色:八卦乾坤,赏心悦目,高 ...
- yii2中事务不能回滚的解决
$player1 = Player::findOne(1); $player1->nickname = '111'; $player2 = Player::findOne(2); $player ...
- JavaScript 中 的prototype和__proto__
1.prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象.它是显示修改对象的原型的属性. 2.__proto__是一个对象拥有的内置属性(请注 ...