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 ...
随机推荐
- java CountDownLatch的使用
CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行.使用一个计数器进行实现.计数器初始值为线程的数量.当每一个线程完成自己任务后,计数器的值就会减一.当计数器的值 ...
- 第12月第25天 ImagePickerSheetController
1.ImagePickerSheetController open class ImagePickerSheetController: UIViewController, UITableViewDat ...
- 【SSH异常】InvalidDataAccessApiUsageException异常
今天在整合SSH的时候,一开始我再测试的时候service层添加了注解事务调用DAO可以正常的保存,在环境中我在XML中采用了spring的OpenSessionInViewFilter解决hiber ...
- python自动安装mysql5.7【转】
#!/usr/bin/env python import os import sys import re base_dir = '/opt/software/mysql-5.7.17-linux-gl ...
- ApiCloud开发经验总结
1. 引擎或模块问题:遇到应用层无法解决的问题,如果能确定需要引擎和模块支持的,不要自己想办法绕过去,要第一时间在开发者社区提交问题,或找APICloud项目经理提出. !!!注意!!!: 在开发者社 ...
- Windows 安装 Go语言开发环境以及使用
下载安装包 下载地址:http://www.golangtc.com/download 32 位请选择名称中包含 windows-386 的 msi 安装包,64 位请选择名称中包含 windows- ...
- ajax发送多个跨域请求回调不混乱
var count = 0; var codes = ""; function refreshCache(urls){ try { var url = urls.split(&qu ...
- laravel的启动过程解析
laravel的启动过程,也是laravel的核心,对这个过程有一个了解,有助于得心应手的使用框架,希望能对大家有点帮助. 统一入口 laravel框架使用了统一入口,入口文件:/public/ind ...
- IOC入门
Spring六大模块 1.SpringCore spring的核心功能:IOC容器,解决对象的创建及依赖关系 2.SpringWeb spring对Web模块的支持 3.SpringDAO s ...
- Java web项目使用webSocket
前端: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8&qu ...