POJ 1741 点分治
方法:指针扫描数组
每次选择树的重心作为树根,从树根出发进行一次DFS,求出点到树根的距离,把节点按照与树根的的距离放进数组d,设置两个指针L,R分别从前、后开始扫描,每次满足条件时答案累加R-L。,之后减去子树的满足条件的情况,删除根节点,对其子树继续上述操作,不断累加答案。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100010;
vector<pair<int,int> >G[maxn];
int d[maxn],size[maxn],root,max_w,n1,cnt,n,k;
bool vis[maxn];
void get_root(int x,int f){//求树的重心
size[x]=1;
int max_part=0;
for(int i=0;i<G[x].size();i++){
int Next=G[x][i].first;
if(Next!=f&&!vis[Next]){
get_root(Next,x);
size[x]+=size[Next];
max_part=max(max_part,size[Next]);
}
}
max_part=max(max_part,n1-size[x]);
if(max_part<max_w){
root=x;
max_w=max_part;
}
}
void get_dist(int x,int f,int dist){//算距离
d[++cnt]=dist;
size[x]=1;//算距离的同时也更新一下子树的大小
for(int i=0;i<G[x].size();i++){
int Next=G[x][i].first;
if(Next!=f&&!vis[Next]){
get_dist(Next,x,dist+G[x][i].second);
size[x]+=size[Next];
}
}
}
int cal(int x,int y){//计算
cnt=0;
get_dist(x,-1,y);
sort(d+1,d+1+cnt);
int ans=0;
for(int i=1,j=cnt;i<j;i++){
while(d[i]+d[j]>k&&i<j)j--;
ans+=j-i;
}
return ans;
}
int dfs(int x){//dfs主框架
max_w=n1;
get_root(x,-1);
int now=root;
vis[now]=1;
int ans=0;
ans+=cal(now,0);
for(int i=0;i<G[now].size();i++){
int Next=G[now][i].first;
if(!vis[Next]){
ans-=cal(Next,G[now][i].second);
n1=size[Next];
ans+=dfs(Next);
}
}
return ans;
}
void init(int n){
for(int i=1;i<=n;i++)G[i].clear();
cnt=0;
memset(vis,0,sizeof(vis));
}
int main(){
int u,v,dis;
while(~scanf("%d%d",&n,&k)&&n&&k){
init(n);
for(int i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&dis);
G[u].push_back(make_pair(v,dis));
G[v].push_back(make_pair(u,dis));
}
n1=n;
printf("%d\n",dfs(1));
}
}
//5 1
//1 2 1
//2 3 1
//3 4 1
//4 5 1
POJ 1741 点分治的更多相关文章
- POJ 1741 树分治
题目链接[http://poj.org/problem?id=1741] 题意: 给出一颗树,然后寻找点对(u,v)&&dis[u][v] < k的对数. 题解: 这是一个很经典 ...
- POJ 1741 [点分治][树上路径问题]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给一棵有n个节点的树,每条边都有一个正权值,求一共有多少个点对使得它们之间路的权值和小于给定的k. 思路: <分治算法在树的路径问题中的应用 ...
- [八分之三的男人] POJ - 1741 点分治 && 点分治笔记
题意:给出一棵带边权树,询问有多少点对的距离小于等于\(k\) 本题解参考lyd的算法竞赛进阶指南,讲解的十分清晰,比网上那些讲的乱七八糟的好多了 不过写起来还是困难重重(史诗巨作 打完多校更详细做法 ...
- 【POJ 1741】 Tree (树的点分治)
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 100 ...
- poj 1741 树的点分治(入门)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 18205 Accepted: 5951 Description ...
- poj 1741 Tree(树的点分治)
poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...
- poj 1741 楼教主男人八题之中的一个:树分治
http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...
- POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量
POJ 1741. Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 34141 Accepted: 11420 ...
- 点分治——POJ 1741
写的第一道点分治的题目,权当认识点分治了. 点分治,就是对每条过某个点的路径进行考虑,若路径不经过此点,则可以对其子树进行考虑. 具体可以看menci的blog:点分治 来看一道例题:POJ 1741 ...
随机推荐
- mybatis中>=和<=的实现方式
原因 mybatis使用的是xml格式的文件.使用>和<号的时候,会存在与xml的标签的规范冲突. 解决方案 >=使用 <![CDATA[>=]]> >< ...
- winform常用方法
1.对象的初始化器: Class a = new Class() { id = , name = "张三" } 2.窗体间传值 ①构造函数 ②单例函数 //单例模式:确 ...
- uva11134 - Fabled Rooks(问题分解,贪心法)
这道题非常好,不仅用到了把复杂问题分解为若干个熟悉的简单问题的方法,更是考察了对贪心法的理解和运用是否到位. 首先,如果直接在二维的棋盘上考虑怎么放不好弄,那么注意到x和y无关(因为两个车完全可以在同 ...
- Spring通过注解方式实现定时任务
XML配置: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:/ ...
- Brackets (区间DP)
个人心得:今天就做了这些区间DP,这一题开始想用最长子序列那些套路的,后面发现不满足无后效性的问题,即(,)的配对 对结果有一定的影响,后面想着就用上一题的思想就慢慢的从小一步一步递增,后面想着越来越 ...
- webpack 配置简单说几句 ?
前言 这几天在准备一个单页面应用, 准备试试webpack神器,在准备webpack下的知识点,顺便记录下一些使用的心得. webpack 的配置说明 在近来的前端开发中,业务逻辑复杂化,层次多样化, ...
- GMchess Linux下的中国象棋游戏
gmchess,一款Linux下的中国象棋程序
- 前端跨域问题,以及ajax,jsonp,json的区别
看了很多网上的资料,小七感觉都没有完全解决我的疑惑以及问题,所以特意拿出通俗易懂的话讲解跨域问题,以及ajax,jsonp,json的区别.首先先说跨域问题什么时候需要跨域?[1]域名不同(即网址不同 ...
- microsoft windows network 不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接
运行CMD在命令行中运行net use * /del /y 命令中断开所有连接最后,你再次访问 ,就不会有问题了. 而且可以连接多个samba用户.
- 减小SSN影响
单板级SSN 从单板级来看,芯片中多个逻辑门同时翻转时,将从单板电源和地平面瞬间汲取较大的电流.任何电源分配系统都存在着阻抗,特别是感抗,导致在短时间内电压调整模块来不及供应这些电流,从而在单板和电源 ...