【POJ1741】Tree
题目大意:给定一棵 N 个节点的无根树,边有边权,统计树上边权和不大于 K 的路径数。
对于每条树上路径,对于每一个点来说,该路径只有经过该点和不经过该点两种情况,对于不经过该点的情况,可以转化成是否经过以该点为树根的子树节点的子问题,由此构成一个分治策略。
对于点分治来说,限制算法复杂度的瓶颈之一是递归的层数,即:子问题的数目。因此,为了避免树退化成一条链,应该每次选取一棵树的重心作为根节点,进行递归求解。层数可以控制在 \(O(logn)\) 级别。
在统计经过每一个点的路径数量时,采用的策略是由该点出发,记录下以该点为根的子树中的每个点到该点的距离,排序后用双指针直接扫描记录贡献。考虑到路径必须经过该点,即:对于同一棵子树中的节点贡献值必须减去,因此在分治子树问题之前,先减去子树内部路径对答案的贡献。
代码如下
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define pb push_back
using namespace std;
const int maxn=1e4+10;
int n,k,ans;
int sn,root,sz[maxn],f[maxn],dep[maxn];
bool vis[maxn];
vector<int> ret;
struct node{
int nxt,to,w;
node(int a=0,int b=0,int c=0):nxt(a),to(b),w(c){}
}e[maxn<<1];
int tot=1,head[maxn];
inline void add_edge(int from,int to,int w){
e[++tot]=node(head[from],to,w),head[from]=tot;
}
void getroot(int u,int fa){
sz[u]=1,f[u]=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa||vis[v])continue;
getroot(v,u);
f[u]=max(f[u],sz[v]);
sz[u]+=sz[v];
}
f[u]=max(f[u],sn-sz[u]);
if(!root||f[u]<f[root])root=u;
}
void getdis(int u,int fa){
ret.pb(dep[u]);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(v==fa||vis[v])continue;
dep[v]=dep[u]+w;
getdis(v,u);
}
}
int calc(int u,int d){
dep[u]=d;
ret.clear();
getdis(u,0);
sort(ret.begin(),ret.end());
int cnt=0,l=0,r=ret.size()-1;
while(l<r){
if(ret[r]+ret[l]<=k)cnt+=r-l,++l;
else --r;
}
return cnt;
}
void dfs(int u){
vis[u]=1;
ans+=calc(u,0);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(vis[v])continue;
ans-=calc(v,w);
root=0,sn=sz[v],getroot(v,0);
dfs(root);
}
}
void read_and_parse(){
for(int i=1;i<n;i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z),add_edge(y,x,z);
}
}
void solve(){
getroot(1,0);
dfs(root);
printf("%d\n",ans);
}
void init(){
memset(head,0,sizeof(head)),tot=1;
memset(vis,0,sizeof(vis));
root=ans=0,sn=n;
}
int main(){
while(scanf("%d%d",&n,&k)&&n&&k){
init();
read_and_parse();
solve();
}
return 0;
}
update at 2019.3.18
【POJ1741】Tree的更多相关文章
- 【POJ1741】Tree(点分治)
[POJ1741]Tree(点分治) 题面 Vjudge 题目大意: 求树中距离小于\(K\)的点对的数量 题解 完全不觉得点分治了.. 简直\(GG\),更别说动态点分治了... 于是来复习一下. ...
- 【poj1741】 Tree
http://poj.org/problem?id=1741 (题目链接) 题意 给出一个n个节点的带权树,求树上距离不超过K的所有点对的个数. solution 点分治裸题.所谓的点分治,就是对于 ...
- 【poj1741】Tree 树的点分治
题目描述 Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dis ...
- 【POJ1741】Tree 树分而治之 模板略?
做广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog. ...
- 【POJ3237】Tree 树链剖分+线段树
[POJ3237]Tree Description You are given a tree with N nodes. The tree's nodes are numbered 1 through ...
- 【BZOJ】【2631】Tree
LCT 又一道名字叫做Tree的题目…… 看到删边加边什么的……又是动态树问题……果断再次搬出LCT. 这题比起上道[3282]tree的难点在于需要像线段树维护区间那样,进行树上路径的权值修改&am ...
- 【Luogu1501】Tree(Link-Cut Tree)
[Luogu1501]Tree(Link-Cut Tree) 题面 洛谷 题解 \(LCT\)版子题 看到了顺手敲一下而已 注意一下,别乘爆了 #include<iostream> #in ...
- 【BZOJ3282】Tree (Link-Cut Tree)
[BZOJ3282]Tree (Link-Cut Tree) 题面 BZOJ权限题呀,良心luogu上有 题解 Link-Cut Tree班子提 最近因为NOIP考炸了 学科也炸了 时间显然没有 以后 ...
- 【AtCoder3611】Tree MST(点分治,最小生成树)
[AtCoder3611]Tree MST(点分治,最小生成树) 题面 AtCoder 洛谷 给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x,y\)之间的边长为\(w[x]+w[y]+di ...
随机推荐
- Helper
//检测端口是否使用 public static bool VerifyListenerPort(int port) { bool inUse = false; System.Net.NetworkI ...
- ACM注意事项
acm竞赛中不能使用一些屏幕控制和键盘读取的函数,如:getch(),geche(),gotoxy(),clrscr(),另外fflush(stdio)这个函数也不能使用,因为在有的编译 ...
- 必应词典案例分析——个人博客作业week3
案例分析 ——必应词典客户端 软件缺陷常常又被叫做Bug,即为计算机软件或程序中存在的某种破坏正常运行能力的问题.错误,或者隐藏的功能缺陷. 缺陷的存在会导致软件产品在某种程度上不能满足用户的需要.I ...
- 《linux内核设计与分析》内核模块编程
内核模块编程 一.准备工作 虚拟机:VMware Workstation 12操作系统:ubuntu当前内核版本:linux-headers-4.4.0-22-generic 二.有关于内核模块的知识 ...
- K Nearest Neighbor 算法
文章出处:http://coolshell.cn/articles/8052.html K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法, 总体来说KN ...
- TMainMenu - 隐藏与显示菜单
//隐藏与显示菜单 Self.Menu := nil; {隐藏菜单} Self.Menu := MainMenu1; {显示菜单}
- Tomcat7/8访问Server Status、Manager App、Host Manager出现403 forbidden
在配置好Tomcat7/8后,我们往往需要访问Tomcat7/8的Manager以及Host Manager.就需要在tomcat-users.xml中配置用户角色来实现.在地址栏输入:localho ...
- Java之修改文件内容:字符串逐行替换
依赖包: <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</a ...
- BZOJ3172[Tjoi2013]单词——AC自动机(fail树)
题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...
- BZOJ1563 NOI2009诗人小G(动态规划+决策单调性)
设f[i]为前i行的最小不协调度,转移枚举这一行从哪开始,显然有f[i]=min{f[j]+abs(s[i]-s[j]+i-j-1-m)p}.大胆猜想有决策单调性就好了.证明看起来很麻烦,从略.注意需 ...