POJ 1741 Tree (树的点分治入门)
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 16172 | Accepted: 5272 |
Description
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 last test case is followed by two zeros.
Output
Sample Input
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0
Sample Output
8


view code#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 10010;
int n, k, pre[N], ans, mi, rt, siz[N], num;
bool vis[N]; struct edge
{
int u, v, w, next;
edge() {}
edge(int u, int v, int w, int next):u(u),v(v),w(w),next(next) {}
}e[N<<1];
int ecnt; void init()
{
ans = ecnt = 0;
memset(pre, -1, sizeof(pre));
memset(vis, 0, sizeof(vis));
} inline void add(int u, int v, int w)
{
e[ecnt] = edge(u, v, w, pre[u]);
pre[u] = ecnt++;
} void getroot(int u, int fa)
{
siz[u] = 1;
int mx = 0;
for(int i=pre[u]; ~i; i=e[i].next)
{
int v = e[i].v;
if(v==fa || vis[v]) continue;
getroot(v, u);
siz[u] += siz[v];
mx = max(mx, siz[v]);
}
mx = max(mx, siz[0]-siz[u]);
if(mx <mi) mi = mx, rt = u;
} int dis[N];
void getdis(int u, int d, int fa)
{
dis[num++] = d;
for(int i=pre[u]; ~i; i=e[i].next)
{
int v = e[i].v;
if(v==fa || vis[v]) continue;
getdis(v, d+e[i].w, u);
}
} int calc(int u, int d)
{
int res = 0;
num = 0;
getdis(u, d, 0);
sort(dis, dis+num);
int i = 0, j = num-1;
while(i<j)// 经典。。
{
while(dis[i]+dis[j]>k && i<j) j--;
res += j-i;
i++;
}
return res;
} void solve(int u, int cnt)
{
mi = n;
siz[0] = cnt;
getroot(u, 0);
ans += calc(rt, 0);
vis[rt] = 1;
for(int i=pre[rt]; ~i; i=e[i].next)
{
int v = e[i].v;
if(vis[v]) continue;
ans -= calc(v, e[i].w);
solve(v, siz[v]);
} } int main()
{
// freopen("in.txt", "r", stdin);
while(scanf("%d%d", &n, &k)>0 && (n|k))
{
int u, v, w;
init();
for(int i=1; i<n; i++)
{
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
solve(1, n);
printf("%d\n", ans);
}
return 0;
}
POJ 1741 Tree (树的点分治入门)的更多相关文章
- POJ 1741 Tree(树的点分治,入门题)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21357 Accepted: 7006 Description ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- 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 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 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 18205 Accepted: 5951 Description ...
随机推荐
- 在selenium2.0中使用selenium1.0的API
Selenium2.0中使用WeDriver API对页面进行操作,它最大的优点是不需要安装一个selenium server就可以运行,但是对页面进行操作不如selenium1.0的Selenium ...
- 灵感来自 Google & YouTube 的苗条的进度栏效果
NProgress.js 是纳米级的进度条插件.拥有逼真的的涓涓细流动画效果来告诉你的用户,某些事情正在发生.它的灵感来自于谷歌,YouTube,应用了,这款苗条的进度条是完美的,适用于 Turbol ...
- JavaScript中对象的比较
Javascript中有'=='和'==='两种相等比较,后者是全等,会判断数据类型,前者是相等,在比较时,会发生隐式转换. 如果将两个对象做'=='比较,结果会如何呢? 比如有如下两个对象: var ...
- 一些XMLHttpRequest的例子代码
以下例子摘录自:javascript权威指南 //异步请求(事件监听请求是否返回) function getText(url,callback){ var request = new XMLHttpR ...
- Bootstrap transition.js 插件详解
Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,而其中的 transition.js 就是为了判断当前使用的浏览器是否支持 CSS 过渡.下面先来简单 ...
- ae IMap接口成员
使用IMap接口显示各种数据源的数据.IMap接口的成员ActiveGraphicsLayer:活动图形图层,如果没有将创建一个基本memory graphics layer.AddLayer:向地图 ...
- Ruby学习心得之 Linux下搭建Ruby环境
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Ruby学习心得之 Linux下搭建Ruby环境1.前言2.Linux下安装Ruby环境 一 ...
- ios线程和GCD
1.什么是进程? 进程是指在系统中正在运行的一个应用程序.比如同时打开QQ.Xcode,系统就会分别启动2个进程.截图 2.什么是线程? 1).一个进程要想执行任务,必须得有线程(每一个进程至少要有一 ...
- Android 获取系统的联系人
本文主要介绍android中怎样获取系统的联系人数据 首先打开模拟器 点击联系人图标按钮 说明系统联系人数据库是空的,打开File explorer,找到data/data下面的文件夹: 将conta ...
- Java中并发问题整理
1. java中有几种方法可以实现一个线程? 使用Runnable,Callable,Thread或者线程池 2. 如何停止一个正在运行的线程? 可以使用正在运行的线程,支持线程中断,通常是定义一个v ...