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 ...
随机推荐
- zTree的简单例子
<%@ page language="java" pageEncoding="UTF-8" %> <%@ include file=" ...
- shiro登录成功之后跳转原路径
通过 WebUtils.getSavedRequest(request) 来获取shiro保存在session登录之前的url 1:java Controller代码 @PostMapping(&qu ...
- Python实现网页截图(PyQT5)
方案说明 功能要求:实现网页加载后将页面截取成长图片涉及模块:PyQT5 PIL逻辑说明: 1:完成窗口设置,利用PyQT5 QWebEngineView加载网页地址,待网页加载完成后,调用check ...
- Windows::Docker::Ubuntu 做 SLAM
如题,这是一件很蛋疼的事情. 为了完成这一件事情,需要达成目标: Ubuntu GUI 必须要能够显示. Ubuntu 可以链接 USB Camera. 目标一 目标1很容易达成. 在 Win10 中 ...
- requests(三):json请求中中文乱码处理
最近收到一个问题:json格式请求数据中有中文,导致服务端签名失败. 问题详情: 一位同学在发送json格式的post请求时,请求数据中有中文内容: {"inputCodes":[ ...
- Springboot 之 自定义配置文件及读取配置文件
本文章来自[知识林] 读取核心配置文件 核心配置文件是指在resources根目录下的application.properties或application.yml配置文件,读取这两个配置文件的方法有两 ...
- nginx开启gzip压缩前端css,js
利用nginx实现前后端分离, nginx配置文件,nginx.conf配置采用gzip压缩: 在server中添加: gzip on; #开启gzip gzip_min_length 1k; #低于 ...
- js里size和length的区别
length: length是js的原生方法,用于获取元素的个数和对象的长度 var length = $(obj).length; size(): size()属于方法,只能作用于对象上,获取元素的 ...
- tomcat启动不成功(点击startup.bat闪退)的解决办法
今天遇到tomcat手动启动不成功,但是再eclipse里面是可以启动成功的.我一直开始以为是端口被占用了,最后才发现是这么一回事.首先说下我的tomcat是安装版的.免安装的tomcat双击star ...
- .NetCore 中使用AppMetrics向InfluxDB中添加监控数据并通过Grafana图像分析
考虑到分布式部署监控环境是所有的请求情况,所以这一块一般在网关GateWay里面加比较省事,聚合在一起的,如果放在api服务中,如果只有1个还好,一旦部署Node多是很痛苦的事情 这天需要添加的Nug ...