【POJ 1741】 Tree (树的点分治)
TreeDescription
Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.Input
The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.Output
For each test case output the answer on a single line.Sample Input
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0Sample Output
8Source
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define Maxn 10010
#define INF 0xfffffff struct node
{
int x,y,c,next;
}t[Maxn*];int len;
int first[Maxn];
int n,k; int mymax(int x,int y) {return x>y?x:y;} void ins(int x,int y,int c)
{
t[++len].x=x;t[len].y=y;t[len].c=c;
t[len].next=first[x];first[x]=len;
}
int rt;
bool q[Maxn];
int sm[Maxn],mx[Maxn],dep[Maxn];
int v[Maxn],vl; void dfs(int x,int h,int f)
{
mx[x]=-;sm[x]=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f&&q[t[i].y])
{
int y=t[i].y;//dep[y]=dep[x]+t[i].c;
dfs(y,h,x);
sm[x]+=sm[y];
mx[x]=mymax(mx[x],sm[y]);
}
mx[x]=mymax(mx[x],h-sm[x]);
if(mx[x]<mx[rt]) rt=x;
} int get_ans()
{
int now=,ans=;
sort(v+,v++vl);
for(int i=vl;i>=;i--)
{
if(now>i) now=i;
while(v[i]+v[now]<=k&&now<i) now++;
ans+=now-;
}
return ans;
} void dfs2(int x,int f)
{
v[++vl]=dep[x];
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f&&q[t[i].y])
{
int y=t[i].y;
dep[y]=dep[x]+t[i].c;
dfs2(y,x);
}
} int fans; void ffind(int x,int f)
{
vl=;dep[x]=;dfs2(x,);
fans+=get_ans();
q[x]=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f&&q[t[i].y])
{
int y=t[i].y;
vl=;dfs2(y,x);
fans-=get_ans();
}int i;
for(i=first[x];i;i=t[i].next)
if(t[i].y!=f&&q[t[i].y])
{
rt=;
dfs(t[i].y,x,sm[t[i].y]);
ffind(rt,x);
}
} int main()
{
while()
{
scanf("%d%d",&n,&k);
if(n==&&k==) break;
memset(first,,sizeof(first));
len=;
for(int i=;i<n;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
ins(x,y,c);ins(y,x,c);
}
fans=;
memset(q,,sizeof(q));
mx[]=INF;
rt=;vl=;dfs(,n,);
ffind(rt,);
printf("%d\n",fans);
}
return ;
}
[POJ 1741]
其实不知道我打的点分治标不标准,感觉很丑。这题就有3个dfs,ffind是求分治的子树答案,dfs是求子树重心,dfs2是求dis以及把子树的dis加入到v中排序。
2016-10-16 22:16:44
【POJ 1741】 Tree (树的点分治)的更多相关文章
- POJ 1741 Tree(树的点分治,入门题)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21357 Accepted: 7006 Description ...
- POJ 1741 Tree 树的分治(点分治)
题目大意:给出一颗无根树和每条边的权值,求出树上两个点之间距离<=k的点的对数. 思路:树的点分治.利用递归和求树的重心来解决这类问题.由于满足题意的点对一共仅仅有两种: 1.在以该节点的子树中 ...
- poj 1741(树的点分治)
Tree Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dis ...
- POJ 1741/1987 树的点分治
树的点分治,主要思想是每次找子树的重心,计算经过根节点的情况数,再减去点对属于同一子树的情况. #include <iostream> #include <vector> #i ...
- POJ 1741.Tree 树分治 树形dp 树上点对
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 24258 Accepted: 8062 Description ...
- POJ 1741 Tree 树的分治
原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- poj 1741 Tree (树的分治)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 30928 Accepted: 10351 Descriptio ...
- POJ 1741 Tree 树形DP(分治)
链接:id=1741">http://poj.org/problem?id=1741 题意:给出一棵树,节点数为N(N<=10000),给出N-1条边的两点和权值,给出数值k,问 ...
- poj 1741 Tree(树的点分治)
poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...
随机推荐
- modelsim remote
远程桌面登陆我的台式机上的账号,然后运行modelsim 出现该问题: Unable to checkout a viewer license necessary for use of the Mod ...
- php文件上传之单文件上传
为了简单一些,php文件跟form表单写在了一个文件里. php单文件上传----> <!DOCTYPE html> <html> <head> <me ...
- 一步一步学NUnit
转载:http://tech.sina.com.cn/s/2009-07-17/1129988785.shtml 单元测试基础知识 单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的.很明 ...
- VIM学习1
不得不说鸟哥的Linux写得太好了,VIM篇章,通读一篇,感觉收获挺大.之前几年前装逼硬着学,感觉硬是没懂,看的特晕,学得特别慢,抄一两遍也没什么多大的作用.这一回看了,感觉马上就能记住不少,当然大多 ...
- TransactionScope事务
一个错误的理解就是Complete()方法是提交事务的,这是错误的,事实上,它的作用的表示本事务完成,它一般放在try{}的结尾处,不用判断前台操作是否成功,如果不成功,它会自己回滚. #region ...
- EDMX更新实体后出现键值映射问题
近期做项目的EF改版时,在DB(ORACLE)中的表里添加一个新的PK,去除原有的PK. 在DB已添加完成操作,但这时在EDMX里进行从DB更新到EF里,更新完成后就发生如下错误提示: Error 6 ...
- spring定时任务的配置
定时任务配置分为三个步骤: 1.定义任务 2.任务执行策略配置 3.启动任务 1.定义任务 <!--要定时执行的方法--> <bean id="testTaskJob&qu ...
- 转JSONObject put,accumulate,element的区别
public Object put (Object key, Object value) 将value映射到key下.如果此JSONObject对象之前存在一个value在这个key下,当前的 ...
- 暑假集训(1)第六弹 -----简单计算器(Hdoj1237)
Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算 ...
- EntityClient 介绍
System.Data.EntityClient 命名空间是 实体框架的 .NET Framework 数据提供程序.EntityClient 提供程序使用存储特定的 ADO.NET 数据提供程序类和 ...