Codeforces 161.D. Distance in Tree-树分治(点分治,不容斥版)-树上距离为K的点对数量-蜜汁TLE (VK Cup 2012 Round 1)
3 seconds
512 megabytes
standard input
standard output
A tree is a connected graph that doesn't contain any cycles.
The distance between two vertices of a tree is the length (in edges) of the shortest path between these vertices.
You are given a tree with n vertices and a positive number k. Find the number of distinct pairs of the vertices which have a distance of exactly k between them. Note that pairs (v, u) and (u, v) are considered to be the same pair.
The first line contains two integers n and k (1 ≤ n ≤ 50000, 1 ≤ k ≤ 500) — the number of vertices and the required distance between the vertices.
Next n - 1 lines describe the edges as "ai bi" (without the quotes) (1 ≤ ai, bi ≤ n, ai ≠ bi), where ai and bi are the vertices connected by the i-th edge. All given edges are different.
Print a single integer — the number of distinct pairs of the tree's vertices which have a distance of exactly k between them.
Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
5 2
1 2
2 3
3 4
2 5
4
5 3
1 2
2 3
3 4
4 5
2
In the first sample the pairs of vertexes at distance 2 from each other are (1, 3), (1, 5), (3, 5) and (2, 4).
这道题就是求树上距离为K的点对数量。以前写过<=K的点对数量,直接<=K的数量 - <K的数量,讲道理应该也是可以的,但是一直TLE11和TLE17样例。。。
最后换了一种写法,直接求,没有中间-子树的过程,最后过了,有点迷。。。
不容斥版的快,就这样。
代码:
//树分治-点分治
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//#pragma GCC optimize(2)
//#define FI(n) FastIO::read(n)
const int inf=1e9+;
const int maxn=1e5+;
const int maxm=+; int head[maxn<<],tot;
int root,allnode,n,m,k;
bool vis[maxn];
int deep[maxn],dis[maxn],siz[maxn],maxv[maxn];//deep[0]子节点个数(路径长度),maxv为重心节点
int num[maxm],cnt[maxm];
ll ans=; //namespace FastIO {//读入挂
// const int SIZE = 1 << 16;
// char buf[SIZE], obuf[SIZE], str[60];
// int bi = SIZE, bn = SIZE, opt;
// int read(char *s) {
// while (bn) {
// for (; bi < bn && buf[bi] <= ' '; bi++);
// if (bi < bn) break;
// bn = fread(buf, 1, SIZE, stdin);
// bi = 0;
// }
// int sn = 0;
// while (bn) {
// for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
// if (bi < bn) break;
// bn = fread(buf, 1, SIZE, stdin);
// bi = 0;
// }
// s[sn] = 0;
// return sn;
// }
// bool read(int& x) {
// int n = read(str), bf;
//
// if (!n) return 0;
// int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
// for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
// if (bf < 0) x = -x;
// return 1;
// }
//}; inline int read()
{
int x=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x;
} struct node{
int to,next,val;
}edge[maxn<<]; void add(int u,int v,int w)//前向星存图
{
edge[tot].to=v;
edge[tot].next=head[u];
edge[tot].val=w;
head[u]=tot++;
} void init()//初始化
{
memset(head,-,sizeof head);
memset(vis,,sizeof vis);
tot=;
} void get_root(int u,int father)//重心
{
siz[u]=;maxv[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==father||vis[v]) continue;
get_root(v,u);//递归得到子树大小
siz[u]+=siz[v];
maxv[u]=max(maxv[u],siz[v]);//更新u节点的maxv
}
maxv[u]=max(maxv[u],allnode-siz[u]);//保存节点size
if(maxv[u]<maxv[root]) root=u;//更新当前子树的重心
} void get_dis(int u,int father)//获取子树所有节点与根的距离
{
if(dis[u]>k) return ;
ans+=num[k-dis[u]];
cnt[dis[u]]++;//计数
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==father||vis[v]) continue;
int w=edge[i].val;
dis[v]=dis[u]+w;
get_dis(v,u);
}
} void cal(int u,int now)
{
for(int i=;i<=k;i++){//初始化,清空
num[i]=;
}
num[]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(vis[v]) continue;
for(int j=;j<=k;j++){//初始化
cnt[j]=;
}
dis[v]=now;
get_dis(v,u);//跑路径
for(int j=;j<=k;j++){
num[j]+=cnt[j];//计数
}
}
} void solve(int u)//分治处理
{
cal(u,);
vis[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
int w=edge[i].val;
if(vis[v]) continue;
allnode=siz[v];
root=;
get_root(v,u);
solve(root);
}
} int main()
{
// FI(n);FI(k);
n=read();k=read();
init();
for(int i=;i<n;i++){
int u,v,w;w=;
// FI(u);FI(v);
u=read();v=read();
add(u,v,w);
add(v,u,w);
}
root=;allnode=n;maxv[]=inf;
get_root(,);
solve(root);
printf("%lld\n",ans);
return ;
}
Codeforces 161.D. Distance in Tree-树分治(点分治,不容斥版)-树上距离为K的点对数量-蜜汁TLE (VK Cup 2012 Round 1)的更多相关文章
- Codeforces 161 D. Distance in Tree (树dp)
题目链接:http://codeforces.com/problemset/problem/161/D 题意: 给你一棵树,问你有多少对点的距离为k. 思路: dp[i][j]表示离i节点距离为j的点 ...
- codeforces 161 D. Distance in Tree(树形dp)
题目链接:http://codeforces.com/problemset/problem/161/D 题意:给出一个树,问树上点到点的距离为k的一共有几个. 一道简单的树形dp,算是一个基础题. 设 ...
- VK Cup 2012 Round 1 D. Distance in Tree (树形dp)
题目:http://codeforces.com/problemset/problem/161/D 题意:给你一棵树,问你两点之间的距离正好等于k的有多少个 思路:这个题目的内存限制首先大一倍,他有5 ...
- 【树形dp】VK Cup 2012 Round 1 D. Distance in Tree
统计树中长度为K的路径条数. 用f[u][k]表示从u结点的子树中出发,终止于u结点的长度为k的路径条数. 边dp边统计答案.为了防止重复统计,在枚举子节点的时候,先将该子节点和当前u结点(和前面已经 ...
- Codeforces VK Cup 2012 Round 3 A. Variable, or There and Back Again(dfs)
题目链接:http://codeforces.com/problemset/problem/164/A 思路:用vector分别保留原图和发图,然后分别从val值为1的点正向遍历,va值为2的点反向遍 ...
- POJ1741--Tree (树的点分治) 求树上距离小于等于k的点对数
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12276 Accepted: 3886 Description ...
- Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 菜鸡只会ABC!
Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 全场题解 菜鸡只会A+B+C,呈上题解: A. Bear and ...
- 洛谷 P3806 【模板】点分治1-树分治(点分治,容斥版) 模板题-树上距离为k的点对是否存在
P3806 [模板]点分治1 题目背景 感谢hzwer的点分治互测. 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入格式 n,m 接下来n-1条边a,b,c描述a到b有一条长度 ...
- Codeforces Round VK Cup 2015 - Round 1 (unofficial online mirror, Div. 1 only)E. The Art of Dealing with ATM 暴力出奇迹!
VK Cup 2015 - Round 1 (unofficial online mirror, Div. 1 only)E. The Art of Dealing with ATM Time Lim ...
随机推荐
- .NET Core程序中,如何获取和设置操作系统环境变量的值
有时候我们在.NET Core程序中需要获取和设置操作系统环境变量的值.本文演示如何使用Environment.GetEnvironmentVariable和Environment.SetEnviro ...
- 局域网访问PHP项目网站 用IP地址进入
先在apache中的 httpd.conf中将 Allow from 127.0.0.1 修改为Allow from all 如果你的是Allow from all的话就不需要改 然后再将 Docum ...
- 4、VUE生命周期
下面是分步骤解释vue生命周期 1.开始:new Vue() 创建vue对象过程还是比较繁琐的,所以创建vue对象是异步执行的. 回调函数:beforeCreate 2.Observe Data 监控 ...
- C#拼音帮助类
如果使用此帮助类需要引用 using Microsoft.International.Converters.PinYinConverter; using NPinyin; 可以在NuGet里面下载 1 ...
- MySQL--用户管理 pymysql 索引
目录 用户管理 创建mysql账户 权限管理 涉及到的表 pymysql 索引 语法 结论 用户管理 主要是为了控制权限,让不同的人只能操作只属于只记得那部分数据 创建mysql账户 账户中涉及三个数 ...
- Idea中编辑后需要重启问题
发布的artifact要用exploded 配置On Update action 和On frame deactivation为Update classes and resources. 编辑完成后, ...
- 编写可维护的JavaScript-随笔(二)
一.注释 1. 单行注释 a) 以两个斜线开始,以行位结束 b) 独占一行的注释,用来解释下一行的代码, c) 注释行之前总有一个空行 d) 缩进层级与下一行代 ...
- consul:connect
官方文档:https://www.consul.io/docs/connect/index.html#getting-started-with-connect consul connect的功能类似与 ...
- Servlet HttpServletResponse对象、HttpServletRequest对象
HttpServletResponse对象(response)的常用方法 setCharacterEncoding("utf-8") //设置响应的编码字符集 setCont ...
- 给WEB DYNPRO 程序创建TCODE
1,创建WDA程序,这里就不介绍了,使用现成的程序:ZCRM_ME_SATISFACTION 2,SE93创建TCODE,输入事物代码ZLYTEST点击创建,选择带参数的事物代码. 3,填写事物WDY ...