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的更多相关文章

  1. [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树

    [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树 题目大意: 给出一个\(n(n\le10^5)\)个结点的树,每条边有 ...

  2. BZOJ2051 : A Problem For Fun

    树的点分治,将点分治的过程记录下来,每一个分治结构按到分治中心的距离维护所有点. 对于一个点二分答案,然后在$O(\log n)$个分治结构中二分查找,时间复杂度$O(n\log^3n)$. #inc ...

  3. 1199 Problem B: 大小关系

    求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...

  4. 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 ...

  5. C - NP-Hard Problem(二分图判定-染色法)

    C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:262144 ...

  6. Time Consume Problem

    I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...

  7. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  8. hdu1032 Train Problem II (卡特兰数)

    题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能.    (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...

  9. BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 4032  Solved: 1817[Submit] ...

随机推荐

  1. wpf 线程

    一.线程概述:[引用MSDN] 通常,WPF 应用程序从两个线程开始:一个用于处理呈现,一个用于管理 UI.呈现线程有效地隐藏在后台运行,而 UI 线程则接收输入.处理事件.绘制屏幕以及运行应用程序代 ...

  2. jQuery关于隐式迭代的个人理解~

    1.JQuery对象" 如: $('div').text("div展示的信息") 可以看成"是一个包含一个dom数组 和 包含所有Jquery方法的容器 2.每 ...

  3. maven学习讲解

    参考链接:http://www.cnblogs.com/bigtall/archive/2011/03/23/1993253.html 1.前言 Maven,发音是[`meivin],"专家 ...

  4. Java观察者设计模式

    在java.util包中提供了Observable类和Observer接口,使用它们即可完成观察者模式. 多个观察者都在关注着价格的变化,只要价格一有变化,则所有的观察者会立即有所行动. //==== ...

  5. Construct Bounding Sphere

    点集的包围球 http://en.wikipedia.org/wiki/Bounding_sphere http://blogs.agi.com/insight3d/index.php/2008/02 ...

  6. FBX Transformation

    2010: http://download.autodesk.com/us/fbx/20102/FBX_SDK_Help/index.html?url=WS1a9193826455f5ff3913a1 ...

  7. CentOS 7学习手册

    CentOS 7与之前版本有较大变动,查阅资料,整理得到如下手册(未完~). 一.安装 1.使用哪种方式安装 (1).虚拟机安装,推荐:VM,功能齐全,强大(Virtual Box也可以). (2). ...

  8. AuthenticationManager.SignOut() 无法注销用户的问题

    http://hadb.me/2015/03/23/authenticationmanager-signout-not-working/ 这文章不对, 我发现原因是不能有Response.Redire ...

  9. osharp3 操作日志之数据日志 控制增强

    osharp3 原来的数据日志,有配置文件中有这总开关,DataLoggingEnabled,原来的程序是,这个总开关关了,就无法记录数据日志了,,如果开了,,他不管记录不记录数据日志,系统都会存数据 ...

  10. 数据库操作事务IsolationLevel 枚举

      成员名称 说明   Chaos 无法覆盖隔离级别更高的事务中的挂起的更改.   ReadCommitted 在正在读取数据时保持共享锁,以避免脏读,但是在事务结束之前可以更改数据,从而导致不可重复 ...