这道题是一道点分治的题目,难度不大,可以拿来练手。

关键是对于找出来的重心的删除操作需要删掉这条边,这很重要。

还有每次找重心的时候,不但要考虑他的子节点的siz,还要考虑父节点的siz。

然后就A了。。。

每次点分治 分两种情况讨论一下就可以啦!

/w\...

#include <cstdio>
#include <algorithm> using namespace std; const int maxn = 56789;
const int INF = 1000000007; int getint()
{
int r = 0, k = 1;
char c;
for (c = getchar(); c < '0' || c > '9'; c = getchar() ) if (c == '-') k = -1;
for (; '0' <= c && c <= '9'; c = getchar() ) r = r * 10 - '0' + c;
return r * k;
} int n, m, k;
int h[maxn], siz[maxn]; struct edge_type
{
int v, next, w;
bool baned;
} edge[maxn * 2]; int tote = 0; void ins(int u, int v, int w)
{
edge[++tote].v = v;
edge[tote].next = h[u];
edge[tote].w = w;
edge[tote].baned = false;
h[u] = tote;
} int fgans, fgsiz; void get_fgans(int now, int fa, int size) {
int tmp = 1;
siz[now] = 1;
for (int i = h[now]; i; i = edge[i].next) {
if (!edge[i].baned && fa != edge[i].v) {
get_fgans(edge[i].v, now, size);
siz[now] += siz[edge[i].v];
if (tmp < siz[edge[i].v]) tmp = siz[edge[i].v];
}
}
if (tmp < size - siz[now]) tmp = size - siz[now];
if (tmp < fgsiz) {
fgans = now;
fgsiz = tmp;
}
}
int find_gravity(int rt, int size) {
fgsiz = INF;
fgans = rt;
get_fgans(rt, -1, size);
return fgans;
} int dis[maxn];
int zhan[maxn], zcnt; void get_dis(int now, int nd, int fa) {
dis[now] = nd;
for (int i = h[now]; i; i = edge[i].next)
if (!edge[i].baned && fa != edge[i].v)
get_dis(edge[i].v, nd + edge[i].w, now);
} void dfs(int now, int fa) {
zhan[++zcnt] = dis[now];
for (int i = h[now]; i; i = edge[i].next)
if (!edge[i].baned && fa != edge[i].v)
dfs(edge[i].v, now);
} int calculate(int rt) {
int ret = 0;
zcnt = 0;
dfs(rt, -1);
sort(zhan + 1, zhan + zcnt + 1);
for (int i = 1, j = zcnt; i <= zcnt; ++i) {
for (; j && zhan[i] + zhan[j] > k; --j);
ret += j;
}
return ret;
} int Ans = 0; void dfz(int now, int size)
{
int rt = find_gravity(now, size);
get_dis(rt, 0, -1);
Ans += calculate(rt);
int v;
for (int i = h[rt]; i; i = edge[i].next)
if (!edge[i].baned) {
edge[i].baned = edge[((i-1)^1)+1].baned = true;
Ans -= calculate(edge[i].v);
dfz(edge[i].v, siz[edge[i].v]);
}
} int main()
{
n = getint();
m = getint();
int u, v, w;
for (int i = 1; i < n; ++i)
{
u = getint();
v = getint();
w = getint();
ins (u, v, w);
ins (v, u, w);
}
k = getint();
dfz(1, n);
printf("%d", (Ans - n >> 1));
return 0;
}

BZOJ 3365 Distance Statistics 点分治的更多相关文章

  1. POJ 1987 BZOJ 3365 Distance Statistics 树的分治(点分治)

    题目大意:(同poj1741,刷一赠一系列) CODE: #include <cstdio> #include <cstring> #include <iostream& ...

  2. [BZOJ 3365] Distance Statistics

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3365 [算法] 点分治 [代码] #include <algorithm> ...

  3. POJ 1987 Distance Statistics 树分治

    Distance Statistics     Description Frustrated at the number of distance queries required to find a ...

  4. BZOJ_3365_[Usaco2004 Feb]Distance Statistics 路程统计&&POJ_1741_Tree_点分治

    BZOJ_3365_[Usaco2004 Feb]Distance Statistics 路程统计&&POJ_1741_Tree_点分治 Description     在得知了自己农 ...

  5. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

  6. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  7. bzoj 3365 [Usaco2004 Feb]Distance Statistics 路程统计(点分治,单调)

    [题意] 求树上长度不超过k的点对数目. [思路] 和 Tree 一样一样的. 就是最后统计的时候别忘把根加上. [代码] #include<set> #include<cmath& ...

  8. bzoj 3365: [Usaco2004 Feb]Distance Statistics 路程统计【容斥原理+点分治】

    统计在一个root下的两个子树,每个子树都和前面的运算一下再加进去对于这种需要排序的运算很麻烦,所以考虑先不去同子树内点对的算出合法点对个数,然后减去每一棵子树内的合法点对(它们实际上是不合法的,相当 ...

  9. BZOJ 3365: [Usaco2004 Feb]Distance Statistics 路程统计

    Description 一棵树,统计距离不大于 \(k\) 的点对个数. Sol 点分治. 发现自己快把点分治忘干净了... 找重心使所有儿子的最大值尽量小,然后每次处理全部子树,再减去每个子树的贡献 ...

随机推荐

  1. MySQL 慢查询日志分析及可视化结果

    MySQL 慢查询日志分析及可视化结果 MySQL 慢查询日志分析 pt-query-digest分析慢查询日志 pt-query-digest --report slow.log 报告最近半个小时的 ...

  2. 【原创】js实现一个可随意拖拽排序的菜单导航栏

    1.想做这个效果的原因主要是用在UC上看新闻发现他们的导航菜单很有趣.无聊的时候在哪划着玩了很久.所以就干脆自己写一个.原效果如下 2.整体效果如下,在已推荐和未添加里面每个小方块可以触摸移动位置互换 ...

  3. <%#Eval if判断用法

    1.绑定Repeater 基础用法 <%#Eval("RoleID")%> 2.简单判断用法 <td> <%# Convert.ToBoolean(E ...

  4. python中如何避免中文是乱码

    这个问题是一个具有很强操作性的问题.我这里有一个经验总结,分享一下,供参考:首先,提倡使用utf-8编码方案,因为它跨平台不错.经验一:在开头声明: # -*- coding: utf-8 -*- 有 ...

  5. hive 表分区操作

    hive的数据查询一般会扫描整个表,当表数据太大时,就会消耗些时间,有时候我们只需要对部分数据感兴趣,所以hive引入了分区的概念    hive的表分区区别于一般的分布式分区(hash分区,范围分区 ...

  6. poj2631 求树的直径裸题

    题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...

  7. KVO 键值观察者

    KVO(键值观察者) //监听的创建 -(id)initChildren:(Person *)person { self = [super init]; if (self != nil) { //拥有 ...

  8. PHP+MySQL+Easyui tree菜单从后台加载json数据(一)

    实现功能:从数据库加载出所有的数据库名,相应的数据库加载对应的数据库表名 原理:(首先看一下参考手册的内容) 异步加载Tree tree 支持内置的异步加载模式,用户创建一个空的tree,然后定义一个 ...

  9. Ubuntu14.10安装Eclipse

    方法一:(缺点是安装时附加openjdk等大量程序并无法去除,优点是安装简单) $ sudo apt-get install eclipse 方法二:(优点是安装内容清爽,缺点是配置麻烦) 1、安装J ...

  10. php排序

    关于order by排序:单条件排序:order by id(按照id排序默认从小到大) order by id desc(按照id排序从大到小) 多条件排序:order by date,id(先按照 ...