POJ 1741 Tree (树分治入门)
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 8554 | Accepted: 2545 |
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
Source
可以看论文。
讲得很明白了。
写分治主要是合并的过程。
/* ***********************************************
Author :kuangbin
Created Time :2013-11-17 14:30:29
File Name :E:\2013ACM\专题学习\树的分治\POJ1741.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to,next,w;
}edge[MAXN*];
int head[MAXN],tot;
void init()
{
tot = ;
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int w)
{
edge[tot].to = v; edge[tot].w = w;
edge[tot].next = head[u];head[u] = tot++;
}
bool vis[MAXN];
int size[MAXN],dep[MAXN];
int le,ri;
int dfssize(int u,int pre)
{
size[u] = ;
for(int i = head[u];i != -;i = edge[i].next)
{
int v = edge[i].to;
if(v == pre || vis[v])continue;
size[u] += dfssize(v,u);
}
return size[u];
}
int minn;
//找重心
void getroot(int u,int pre,int totnum,int &root)
{
int maxx = totnum - size[u];
for(int i = head[u];i != -;i = edge[i].next)
{
int v = edge[i].to;
if(v == pre || vis[v])continue;
getroot(v,u,totnum,root);
maxx = max(maxx,size[v]);
}
if(maxx < minn){minn = maxx; root = u;}
}
void dfsdepth(int u,int pre,int d)
{
dep[ri++] = d;
for(int i = head[u];i != -;i = edge[i].next)
{
int v = edge[i].to;
if(v == pre || vis[v])continue;
dfsdepth(v,u,d+edge[i].w);
}
}
int k;
int getdep(int a,int b)
{
sort(dep+a,dep+b);
int ret = , e = b-;
for(int i = a;i < b;i++)
{
if(dep[i] > k)break;
while(e >= a && dep[e] + dep[i] > k)e--;
ret += e - a + ;
if(e > i)ret--;
}
return ret>>;
}
int solve(int u)
{
int totnum = dfssize(u,-);
int ret = ;
minn = INF;
int root;
getroot(u,-,totnum,root);
vis[root] = true;
for(int i = head[root];i != -;i = edge[i].next)
{
int v = edge[i].to;
if(vis[v])continue;
ret += solve(v);
}
le = ri = ;
for(int i = head[root];i != -;i = edge[i].next)
{
int v = edge[i].to;
if(vis[v])continue;
dfsdepth(v,root,edge[i].w);
ret -= getdep(le,ri);
le = ri;
}
ret += getdep(,ri);
for(int i = ;i < ri;i++)
{
if(dep[i] <= k)ret++;
else break;
}
vis[root] = false;
return ret;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
int u,v,w;
while(scanf("%d%d",&n,&k) == )
{
if(n == && k == )break;
init();
for(int i = ;i < n;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
memset(vis,false,sizeof(vis));
printf("%d\n",solve());
}
return ;
}
POJ 1741 Tree (树分治入门)的更多相关文章
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- POJ 1741.Tree 树分治 树形dp 树上点对
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 24258 Accepted: 8062 Description ...
- poj 1741 Tree (树的分治)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 30928 Accepted: 10351 Descriptio ...
- poj 1744 tree 树分治
Tree Time Limit: 1000MS Memory Limit: 30000K Description Give a tree with n vertices,each ed ...
- POJ 1741 Tree ——点分治
[题目分析] 这貌似是做过第三道以Tree命名的题目了. 听说树分治的代码都很长,一直吓得不敢写,有生之年终于切掉这题. 点分治模板题目.自己YY了好久才写出来. 然后1A了,开心o(* ̄▽ ̄*)ブ ...
- POJ 1741 Tree(树的点分治,入门题)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21357 Accepted: 7006 Description ...
- POJ 1741 Tree 树的分治
原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...
- Tree POJ - 1741【树分治】【一句话说清思路】
因为该博客的两位作者瞎几把乱吹(" ̄︶ ̄)人( ̄︶ ̄")用彼此的智慧总结出了两条全新的定理(高度复杂度定理.特异根特异树定理),转载请务必说明出处.(逃 Pass:anuonei, ...
- POJ 1741 Tree 树的分治(点分治)
题目大意:给出一颗无根树和每条边的权值,求出树上两个点之间距离<=k的点的对数. 思路:树的点分治.利用递归和求树的重心来解决这类问题.由于满足题意的点对一共仅仅有两种: 1.在以该节点的子树中 ...
- POJ 1741 Tree(点分治点对<=k)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
随机推荐
- 第8月第22天 python scrapy
1. cd /Users/temp/Downloads/LagouSpider-master ls ls ls lagou/settings.py cat lagou/settings.py ls p ...
- yui压缩JS和CSS文件
CSS和JS文件经常需要压缩,比如我们看到的XX.min.js是经过压缩的JS. 压缩文件第一个是可以减小文件大小,第二个是对于JS文件,默认会去掉所有的注释,而且会去掉所有的分号,也会将我们的一些参 ...
- Linux内核源码分析--内核启动之(1)zImage自解压过程(Linux-3.0 ARMv7) 【转】
转自:http://blog.chinaunix.net/uid-25909619-id-4938388.html 研究内核源码和内核运行原理的时候,很总要的一点是要了解内核的初始情况,也就是要了解内 ...
- 新手学习爬虫之创建第一个完整的scrapy工程-糗事百科
创建第一个scrapy工程-糗事百科 最近不少小伙伴儿,问我关于scrapy如何设置headers的问题,时间久了不怎么用,还真有的忘,全靠记忆去写了,为了方便大家参考,也方便我以后的查阅,这篇文章就 ...
- mac ssh 自动登陆设置
1.首先找到.ssh目录 一般在用户名目录下. ls -a查看 如果没有就重新创建一个 chennan@bogon :mkdir .ssh chennan@bogon 查看当前的 bogon:.ssh ...
- eclipse开发mapreduce程序时出现的问题
1.报HDFS权限不够:org.apache.hadoop.security.AccessControlException: Permission denied:user=ouqiping, acce ...
- unmappable character for US-ASCII
编码错误编译时加-encoding UTF-8即可 :javac -encoding UTF- file.java //
- spring boot + vue + element-ui
spring boot + vue + element-ui 一.页面 1.布局 假设,我们要开发一个会员列表的页面. 首先,添加vue页面文件“src\pages\Member.vue” 参照文档h ...
- foxmail占cpu 100%解决办法
Win10,x64 Foxmail 7.2.9.075 解决办法: 1. 删除文件夹 d:\Program Files\Foxmail\Storage\邮箱\Indexes2. 菜单 –>帮助 ...
- pageHelper 排序 +- 字符串处理
自己记录一下. 前端要把sort参数传过来, 1. 如果约定是下面这种形式: sort=id-name+age+ 直接在java后台进行替换就行,连正则都不用. sort = sort.replace ...