Problem Tree
题目大意
给一棵树,有边权。求树上距离小于等于K的点对有多少。
解题分析
点分治。对每一棵子树进行dfs,求出每棵子树的重心,继而转化为子问题。
对于经过根的路径i--j,令dep为到根距离,那么需求出dep[i]+dep[j]<=k,且i,j属于不同子树,可以求其补集,求出属于同一子树的对答案贡献。
参考程序
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 100008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define bitcnt(x) __builtin_popcount(x)
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/ int n,k,sum,tot,root,ans;
int lt[N],f[N],vis[N],size[N],a[N];
struct line{int u,v,w,nt;}eg[N*];
vector <int> vec;
void add(int u,int v,int w)
{
eg[++sum]=(line){u,v,w,lt[u]};
lt[u]=sum;
}
void init()
{
clr(lt,); sum=; ans=;
clr(f,); f[]=INF;
clr(vis,);
}
void getRoot(int u,int fa)
{
size[u]=; f[u]=;
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (vis[v] || v==fa) continue;
getRoot(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
f[u]=max(f[u],tot-size[u]);
if (f[u]<f[root]) root=u;
}
void getDeep(int u,int fa)
{
vec.push_back(a[u]);
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (v==fa || vis[v]) continue;
a[v]=a[u]+eg[i].w;
getDeep(v,u);
}
}
int cal(int u,int key)
{
a[u]=key; vec.clear();
getDeep(u,);
sort(vec.begin(),vec.end());
int tmp=,l=,r=vec.size()-;
while (l<r)
{
if (vec[l]+vec[r]<=k)
{
tmp+=r-l;
l++;
}
else r--;
}
return tmp;
}
void work(int u)
{
ans+=cal(u,);
vis[u]=;
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (vis[v]) continue;
ans-=cal(v,eg[i].w);
tot=size[v]; root=;
getRoot(v,u);
work(root);
}
}
int main()
{
while (~scanf("%d%d",&n,&k))
{
if (n==) break;
init();
rep(i,,n-)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w); add(v,u,w);
}
tot=n; root=;
getRoot(,);
work(root);
printf("%d\n",ans);
}
}
poj1741 (点分治)的更多相关文章
-
POJ1741 点分治模板
传送门:http://poj.org/problem?id=1741 题意: 求树上两点间路径长度小于k的点对个数 题解: 参考资料 守望的淀粉质略解:https://www.luogu.org/bl ...
-
POJ-1741 树上分治--点分治(算法太奇妙了)
给你1e5个节点的树,(⊙﹏⊙) 你能求出又几对节点的距离小于k吗??(分治NB!) 这只是一个板子题,树上分治没有简单题呀!(一个大佬说的) #include<cstdio> #incl ...
-
Codeforces 293E 点分治+cdq
Codeforces 293E 传送门:https://codeforces.com/contest/293/problem/E 题意: 给你一颗边权一开始为0的树,然后给你n-1次操作,每次给边加上 ...
-
POJ1741 Tree(树分治——点分治)题解
题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...
-
【POJ1741】Tree(点分治)
[POJ1741]Tree(点分治) 题面 Vjudge 题目大意: 求树中距离小于\(K\)的点对的数量 题解 完全不觉得点分治了.. 简直\(GG\),更别说动态点分治了... 于是来复习一下. ...
-
POJ1741 Tree + BZOJ1468 Tree 【点分治】
POJ1741 Tree + BZOJ1468 Tree Description Give a tree with n vertices,each edge has a length(positive ...
-
[bzoj1468][poj1741]Tree_点分治
Tree bzoj-1468 poj-1741 题目大意:给你一颗n个点的树,求树上所有路径边权和不大于m的路径条数. 注释:$1\le n\le 4\cdot 10^4$,$1\le m \le 1 ...
-
Cogs 1714. [POJ1741][男人八题]树上的点对(点分治)
[POJ1741][男人八题]树上的点对 ★★★ 输入文件:poj1741_tree.in 输出文件:poj1741_tree.out 简单对比 时间限制:1 s 内存限制:256 MB [题目描述] ...
-
poj1741(入门点分治)
题目链接:https://vjudge.net/problem/POJ-1741 题意:给出一棵树,求出树上距离不超过k的点对数量. 思路:点分治经典题.先找重心作为树根,然后求出子树中所有点到重心的 ...
-
POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
随机推荐
-
Effective Java 56 Adhere to generally accepted naming conventions
Typographical naming conventions Identifier Type Type Examples Package com.google.inject, org.joda.t ...
-
Palindromic Number (还是大数)
A number that will be the same when it is written forwards or backwards is known as a Palindromic Nu ...
-
绘图quartz之渐变
实现线性渐变 径向渐变 自己新建的view中有一个drawRect:(cgrect)rect方法 在这个方法里 可以通过画图 将内容显示在画板上(即最下边的view) 渐变的方式分两种 ...
-
改进RazorPad
从Git 上下载了作者的源码后,感觉用起来挺别扭,而且还要BUG............ 经过“篡改”后,好用多了,呵呵..
-
C库函数标准编程之fscanf()函数解读及其实验
函数功能 fscanf()函数用于从参数stream的文件流中读取format格式的内容,然后存放到...所指定的变量中去.字符串以空格或换行符结束(实验1中会对它进一步说明) 函数格式 字符格式说明 ...
-
Strategy 设计模式 策略模式 超靠谱原代码讲解
先来假设一种情,我们需要向三种不同的客户做出不同的报价,一般来说要肿么设计呢,是不是马上会想到用IF,没有错,对于这种情况,策略模式是最好的选.大家可以这么理解,如果有情况需要用到大量的IF,那你用策 ...
-
折腾Java设计模式之单例模式
博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...
-
npm 如何查看一个包的版本信息?
转载. https://blog.csdn.net/cvper/article/details/79543262 有了npm 我们能够简单的一段代码就下载我们需要的包,但是包是不断更新的, 所以我们要 ...
-
js Location
window.location用來返回頁面的地址,并把頁面重定向新的頁面: location.pathname:返回當前的頁面地址和文件名 location.hostname:主機名 location ...
-
Confluence无法打开编辑器,一直在转圈
在管理员界面中,将Collaborative editing 设置为Off 或者 Limited . 快速找到该界面的方式是,在搜索框里搜索 “Collaborative editing”. 折腾了几 ...