http://blog.csdn.net/woshi250hua/article/details/7723400

求两点间距离小于等于k的方案数

理一下思路:

求通过点A与另一点连接符合条件的个数 = 到点A距离相加符合条件个数 - A内部符合条件的个数

步骤:

因为从哪个点开始都一样,所以每次找子树重心开始遍历

求出子节点到这个点的所有距离,排序搜索,得出总方案数

减掉内部符合条件的数量,得到通过这个点的方案数

以此遍历每个点

注意:

求重心时,因为每次子树数量都是不一样的,要动态更新

相向搜索:O(n)

sort(dis,dis+tot);
int left =,right = tot-;
while(left<right)
{
if(dis[left]+dis[right]<=k)
{
ans-= right-left;
left++;
}
else right--;
}

AC代码:

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std; #define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define MAXN 20000+5
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue
#define INF 0x3f3f3f3f #define ls (rt<<1)
#define rs (rt<<1|1) int n,m,k; int ptr = ,head[MAXN],vis[MAXN]; int num,ans,tot,rt,sum,son[MAXN],dis[MAXN],mu[MAXN]; struct node
{
int y,val,next;
}tree[MAXN<<]; void add(int fa,int son,int val)
{
tree[ptr].y = son;
tree[ptr].val = val;
tree[ptr].next = head[fa];
head[fa] = ptr++;
} void getroot(int root,int fa)
{
son[root] = ;
int tmp = ;
for(int i=head[root];i!=-;i=tree[i].next)
{
int y = tree[i].y;
if(vis[y] || y == fa) continue;
getroot(y,root);
son[root] += son[y];
tmp = max(son[y],tmp);
mu[root] = max(mu[root],son[y]);
}
tmp = max(tmp,sum-son[root]);
if(tmp<num)
{
num = tmp;
rt = root;
}
} void getdis(int root,int fa,int dist)
{
dis[tot++] = dist;
for(int i=head[root];i!=-;i=tree[i].next)
{
int y = tree[i].y;
if(vis[y] || y == fa || dist+tree[i].val > k) continue;
getdis(y,root,dist+tree[i].val);
}
} void getcnt()
{
sort(dis,dis+tot);
int left =,right = tot-;
while(left<right)
{
if(dis[left]+dis[right]<=k)
{
ans+= right-left;
left++;
}
else right--;
}
} void getcnt2(int root)
{
vis[root] = ;
for(int i=head[root];i!=-;i=tree[i].next)
{
int y = tree[i].y;
if(vis[y]) continue;
tot = ;
getdis(y,root,tree[i].val);
sort(dis,dis+tot);
int left =,right = tot-;
while(left<right)
{
if(dis[left]+dis[right]<=k)
{
ans-= right-left;
left++;
}
else right--;
}
}
} void solve(int root,int fa)
{
num = sum = son[root];
getroot(root,fa);
tot = ;
getdis(rt,,);
getcnt();
getcnt2(rt);
for(int i=head[rt];i!=-;i=tree[i].next)
{
int y = tree[i].y;
if(vis[y] || y==fa) continue;
solve(y,rt);
}
} int main()
{
int i,j,t,kase=;
while(~sf("%d%d",&n,&k),n+k)
{
mem(tree,);
mem(head,-);
mem(vis,);
mem(dis,);
ans = ;
ptr = ;
son[] = n;
int x,y,z;
for(i=;i<n;i++)
{
sf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
solve(,);
pf("%d\n",ans);
}
return ;
}
/*
5 3
1 2 1
2 3 1
3 4 1
4 5 1
*/

poj 1741 两点距离小于K(树DP)的更多相关文章

  1. poj 1987 节点距离小于等于K(树DP)

    这题和poj 1741是一模一样的 但是1741能AC的代码,在这里却是TLE,暂时没看出哪里出现了问题.. AC代码: #include <iostream> #include < ...

  2. Life Forms POJ - 3294(不小于k个字符串中的最长子串)

    题意: 求不小于字符串一半长度个字符串中的最长字串 解析: 论文题例11 将n个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开, 求后缀数组, 然后二分答案变为判定性问题, 然后判断每组的 ...

  3. Common Substrings POJ - 3415(长度不小于k的公共子串的个数)

    题意: 给定两个字符串A 和 B, 求长度不小于 k 的公共子串的个数(可以相同) 分两部分求和sa[i-1] > len1  sa[i] < len1  和  sa[i-1] < ...

  4. [51NOD1405] 树的距离之和(树DP)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1405 (1)我们给树规定一个根.假设所有节点编号是0-(n-1 ...

  5. POJ 1741 Tree 树形DP(分治)

    链接:id=1741">http://poj.org/problem?id=1741 题意:给出一棵树,节点数为N(N<=10000),给出N-1条边的两点和权值,给出数值k,问 ...

  6. POJ - 1741 Tree

    DescriptionGive a tree with n vertices,each edge has a length(positive integer less than 1001).Defin ...

  7. POJ 1741 Tree 求树上路径小于k的点对个数)

                                                                                                 POJ 174 ...

  8. 树的点分治 (poj 1741, 1655(树形dp))

    poj 1655:http://poj.org/problem?id=1655 题意: 给无根树,  找出以一节点为根,  使节点最多的树,节点最少. 题解:一道树形dp,先dfs 标记 所有节点的子 ...

  9. POJ 1741 Tree(树的点分治,入门题)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21357   Accepted: 7006 Description ...

随机推荐

  1. equals和==的区别 (Java基础)

    1. == 是一个运算符.2.Equals则是string对象的方法,可以.(点)出来. 我们比较无非就是这两种 1.基本数据类型比较 2.引用对象比较 1.基本数据类型比较 ==和Equals都比较 ...

  2. loj #2023. 「AHOI / HNOI2017」抛硬币

    #2023. 「AHOI / HNOI2017」抛硬币   题目描述 小 A 和小 B 是一对好朋友,他们经常一起愉快的玩耍.最近小 B 沉迷于**师手游,天天刷本,根本无心搞学习.但是已经入坑了几个 ...

  3. 老男孩Day6作业:计算器

    作业需求: 1.实现加减乘除及拓号优先级解析 2.用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) ...

  4. anularjs前端分页

    var dataList = []; $scope.page = { page:1, pageSize:15, numPerPageOpt:[15,30,50,100], totalNum:0, to ...

  5. pf4j实例 插件框架

    实现整个过程需要三个部分,第一就是根接口,第二是插件,第三是应用程序.这是3个java项目. 首先要下载jar包,百度搜索maven repository,然后搜索pf4j,如下图,下载第一个的相应版 ...

  6. Codeforces Round #503 (by SIS, Div. 2)B 1020B Badge (拓扑)

    题目大意:每个同学可以指定一个人,然后构成一个有向图.1-n次查询,从某个人开始并放入一个东西,然后循环,直到碰到一个人已经放过了,就输出. 思路:直接模拟就可以了,O(n^2) 但是O(n)也可以实 ...

  7. springcloud系列二 搭建注册中心启动

    创建modul 然后就创建完成了 添加yml文件: server: port: eureka: client: register-with-eureka: false #单机版建议设置为false,设 ...

  8. django ORM 连表查询

    db_index=True  如果设置该字段就可以设置索引 auto_now_add  代表设置创建时候的时间 auto_now   每次更新数据记录时会更新该字段 to_field 设置要关联表的字 ...

  9. django文件配置

    先是 staticfile 文件配制 STATTCFILE=(os.path.join(BASE_DIR,'static'),) 然后是数据库配置  : DATABASES = { 'default' ...

  10. Java——socket

    Server: import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public cla ...