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. 问题导向VS目标导向:领导者要倾向哪种?

    人类进步的驱动: 问题驱动:目标驱动: 两者相互影响: 问题驱动是起点,并且在很多杂乱的问题中只有少数可以转化为目标,从而成为进步的动力:多数问题只是以干扰的形式出现. 问题驱动是被动的,并且常常干扰 ...

  2. 【原】http缓存与cdn相关技术

    摘要:最近要做这个主题的组内分享,所以准备了一个星期,查了比较多的资料.准备的过程虽然很烦很耗时间,不过因为需要查很多的资料,因此整个过程下来,对这方面的知识影响更加深刻.来来来,接下来总结总结 一 ...

  3. Socket通信的理解

    1.Socket(套接字) 是支持TCP/IP通信的基本操作单元.包含通信的五种必须信息:通信使用的协议,本机IP和端口,远程IP和端口. 2. 1.TCP连接 手机能够使用联网功能是因为手机底层实现 ...

  4. 9月6日表格标签(table、行、列、表头)(补)

    一.<table> <table>代表表格标签.   <table></table> 1.width  表示表格宽度,宽度表达方式有像素和百分比两种.网 ...

  5. 第4章 jQuery的事件和动画(二)

    二. jQuery中的动画 动画在前面几章案例中是回避不了的问题.此处结合一些简便的写法稍作系统的分析. 1. show()和hide()(1)介绍——不用过多的介绍了jQuery最基本的方法.本质是 ...

  6. VC----SDK下对窗口非客户区的操作

    窗口分成两大部分:客户区和非客户区.非客户区再次细分:标题栏,如图片中顶部深蓝色:左边框,如图片中红色部分:上边框,如图片中绿色部分:右边框,如图片中右侧天蓝色部分:底边框,如图片中下面棕色部分. 之 ...

  7. python中,ascii,unicode,utf8,gbk之间的关系梳理

    在计算机中,经常遇到编码问题,本节主要梳理下ascii,unicode,utf8,gbk 这几种编码之间的关系. ASCII 计算机中,所有数据都以0和1来表示.在一开始的时候,要表示的内容比较少,人 ...

  8. log4j2 使用

    转载自 Blog of 天外的星星: http://www.cnblogs.com/leo-lsw/p/log4j2tutorial.html Log4j 2的好处就不和大家说了,如果你搜了2,说明你 ...

  9. PuzzleGame部分核心算法

    #include   "mainwindow.h" #include   <QGridLayout> #include   <QPushButton> #i ...

  10. Yii2的深入学习--自动加载机制(转)

    Yii2 的自动加载分两部分,一部分是 Composer 的自动加载机制,另一部分是 Yii2 框架自身的自动加载机制. Composer自动加载 对于库的自动加载信息,Composer 生成了一个  ...