链接:

https://www.acwing.com/problem/content/254/

题意:

给定一个有N个点(编号0,1,…,N-1)的树,每条边都有一个权值(不超过1000)。

树上两个节点x与y之间的路径长度就是路径上各条边的权值之和。

求长度不超过K的路径有多少条。

思路:

点分治, 就是将一棵树根据他的重心分成多颗子树求解.

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e4+10;
const int INF = 1e9; struct Edge
{
int to;
int dis;
};
vector<Edge> G[MAXN];
int Size[MAXN], Cnt[MAXN];
int Vis[MAXN], Dis[MAXN];
int root, maxroot;
int n, k, cnt, treesize;
LL ans = 0; void GetRoot(int u, int fa)
{
Size[u] = 1;
int num = 0;
for (int i = 0;i < G[u].size();i++)
{
int to = G[u][i].to;
if (to == fa || Vis[to] == 1)
continue;
GetRoot(to, u);
Size[u] += Size[to];
num = max(num, Size[to]);
}
num = max(num, treesize-Size[u]);
if (num < maxroot)
{
root = u;
maxroot = num;
}
} void GetDis(int u, int fa)
{
Cnt[++cnt] = Dis[u];
for (int i = 0;i < G[u].size();i++)
{
int to = G[u][i].to;
if (to == fa || Vis[to] == 1)
continue;
Dis[to] = Dis[u] + G[u][i].dis;
GetDis(to, u);
}
} LL Cal(int u, int val)
{
cnt = 0;
Dis[u] = val;
GetDis(u, 0);
LL sum = 0;
int l = 1, r = cnt;
sort(Cnt+1, Cnt+1+cnt);
while (l < r)
{
if (Cnt[l]+Cnt[r] <= k)
sum += r-l, ++l;
else
--r;
}
return sum;
} void Dfs(int u)
{
ans += Cal(u, 0);
Vis[u] = 1;
for (int i = 0;i < G[u].size();i++)
{
int to = G[u][i].to;
if (Vis[to] == 1)
continue;
ans -= Cal(to, G[u][i].dis);
treesize = Size[to];
maxroot = INF;
GetRoot(to, 0);
Dfs(root);
}
} int main()
{
while(~scanf("%d%d", &n, &k) && (n||k))
{
ans = 0;
for (int i = 1;i <= n;i++)
G[i].clear();
memset(Vis, 0, sizeof(Vis));
memset(Size, 0, sizeof(Size));
memset(Cnt, 0, sizeof(Cnt));
int u, v, w;
for (int i = 1;i < n;i++)
{
scanf("%d%d%d", &u, &v, &w);
u++, v++;
// cout << u << ' ' << v << ' ' << w << endl;
G[u].push_back(Edge{v, w});
G[v].push_back(Edge{u, w});
}
treesize = n;
maxroot = INF;
GetRoot(1, 0);
Dfs(root);
printf("%lld\n", ans);
} return 0;
}

Acwing-252-树(点分治)的更多相关文章

  1. AcWing 252. 树 (点分治)打卡

    题目:https://www.acwing.com/problem/content/254/ 题意:求一棵树上,路径<=k的有多少条 思路:点分治,我们用两个指针算solve函数,首先对算出来的 ...

  2. hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)

    题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...

  3. 洛谷P3248 树 [HNOI2016] 主席树+倍增+分治

    正解:主席树+倍增+分治 解题报告: 传送门! 首先看到这题会想到之前考过的这题 但是那题其实简单一些,,,因为那题只要用个分治+预处理就好,只是有点儿思维难度而已 这题就不一样,因为它说了是按照原树 ...

  4. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  5. POJ 1741 Tree 树的分治

    原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...

  6. hdu 4871 树的分治+最短路记录路径

    /* 题意:给你一些节点和一些边,求最短路径树上是k个节点的最长的路径数. 解:1.求出最短路径树--spfa加记录 2.树上进行操作--树的分治,分别处理子树进行补集等运算 */ #include& ...

  7. hdu 4670 树的分治-求点对的个数

    /* 树的分治 因为树的点权值可达到10^15,注意手动扩栈,还有int64 题意:给你一棵树,给你一些素数,给你每个点一个权值且每个权值均可由这些素数组成.现在定义任意任意两点的价值为他们路径上的权 ...

  8. bzoj3648: 寝室管理(环套树+点分治)

    好题..写了两个半小时hh,省选的时候要一个半小时内调出这种题目还真是难= = 题目大意是给一棵树或环套树,求点距大于等于K的点对数 这里的树状数组做了一点变换.不是向上更新和向下求和,而是反过来,所 ...

  9. UVALive 7148 LRIP(树的分治+STL)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  10. 【BZOJ-4435】Juice Junctions 最小割树(分治+最小割)+Hash

    4435: [Cerc2015]Juice Junctions Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 20  Solved: 11[Submi ...

随机推荐

  1. mysql oracle postgresql 体系架构对比

    2个角度sqlservermysqloracle 12cpostgresql如果从create database角度来看 那么一个实例是可以对应多个数据库的~如果从实例和磁盘上的数据库文件(数据文件. ...

  2. P1541 乌龟棋(动态规划)

    (点击此处查看原题) 题意 此处有n个位置,记为1~n,每个位置上都对应一个权值,乌龟从编号为1的位置出发,利用m张爬行卡片到达位置n,爬行卡牌有四种,分别可以让乌龟移动1,2,3,4步,并保证将m张 ...

  3. matplotlib库绘制散点图

    假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温随时间(天)变化的某种规律? a = [11,17,16,11,12,11,12,6,6 ...

  4. C++ MinGW 配合 Sublime Text 搭建

    本文主旨 使用MinGW 和 文本编辑器 Sublime Text,来搭建c++编译的平台. Sublime Text 安装 和 解除限制 http://rainss.cn/essay/1124.ht ...

  5. 分词搜索 sphinx3.1.1+php+mysql

    sphinx3.1.1的安装与使用 下载sphinx3.1.1 wget http://sphinxsearch.com/files/sphinx-3.1.1-612d99f-linux-amd64. ...

  6. Linux的一个后门引发对PAM的探究

    转自http://www.91ri.org/16803.html 1.1   起因 今天在搜索关于Linux下的后门姿势时,发现一条命令如下:软链接后门: 1 ln -sf /usr/sbin/ssh ...

  7. Ruby Rails学习中:Ruby内置的辅助方法,基础内容回顾补充

    一. Ruby内置的辅助方法 1.打开文件:app/views/layouts/application.html.erb(演示应用的网站布局) 来咱把注意力放在圈起来的那一行: 这行代码使用 Rail ...

  8. 面试常考的js题目(三)

    1.查找两个节点的最近的一个共同父节点,可以包括节点自身 function commonParentNode(oNode1, oNode2) { if(oNode1.contains(oNode2)) ...

  9. [转载]flex中的正则表达式

    原文:https://blog.csdn.net/hczhiyue/article/details/20483209 (1)单字符匹配* ‘x’ 匹配字符 x.* ‘.’ 匹配任意一个字符(字节),除 ...

  10. vue-loading图

    父组件给子组件src地址: columns(){ return [ {'title': '图片', 'key': 'img', render(h, {row}){ return h(LoadingIm ...