博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[POJ1741]Tree(点分治)
阅读量:6567 次
发布时间:2019-06-24

本文共 1107 字,大约阅读时间需要 3 分钟。

树分治之点分治入门

所谓点分治,就是对于树针对点的分治处理

首先找出重心以保证时间复杂度

然后递归处理所有子树

 

对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况

  1. 路径过当前根
  2. 路径在子树中(递归处理)

那么关键就是如何计算第一种情况

设d[i]表示点i到当前根rt的距离,可以将d数组排序后线性复杂度求

然而此时会有些点对是在同一棵子树中,这些情况要减去

注意每次递归都要找一次重心以保证效率

这样复杂度就是O(nlog2n)

Code

#include 
#include
#include
#define Inf 0x7fffffff#define N 10010using namespace std;struct info{int to,nex,w;}e[N*2];int n,k,tot,head[N],d[N],rt,Ans,sum,f[N],sz[N],dep[N];bool vis[N];void Link(int u,int v,int w){ e[++tot].nex=head[u];head[u]=tot;e[tot].to=v;e[tot].w=w;}inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void getrt(int u,int fa){ sz[u]=1,f[u]=0; for(int i=head[u];i;i=e[i].nex){ int v=e[i].to; if(v==fa||vis[v]) continue; getrt(v,u); sz[u]+=sz[v]; f[u]=max(f[u],sz[v]); } f[u]=max(f[u],sum-sz[u]); if(f[rt]>f[u]) rt=u;}void Init(){ tot=0,rt=0,Ans=0; memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); for(int i=1;i

 

转载于:https://www.cnblogs.com/void-f/p/9102070.html

你可能感兴趣的文章
《Spring 5 官方文档》26. JMS(一)
查看>>
《Python Cookbook(第2版)中文版》——1.11 检查一个字符串是文本还是二进制
查看>>
Tkinter之Label
查看>>
PostgreSQL merge json的正确姿势
查看>>
java反射
查看>>
【IOS-COCOS2D游戏开发之二】COCOS2D 游戏开发资源贴(教程以及源码)
查看>>
nodejs安装记录
查看>>
Android2.2 API 中文文档系列(9) —— ZoomButton
查看>>
pcDuino 刷系统-卡刷
查看>>
MySQL结构自动同步工具-schemasync
查看>>
关于在线代码运行网站的一个想法
查看>>
我的友情链接
查看>>
使用subeclipse来管理分支/标记
查看>>
我的友情链接
查看>>
django forms模块使用
查看>>
FreeBSD IPFW 防火墙的安装和设置
查看>>
Linux分区和文件系统 ⑥
查看>>
ClipDrawable--水漫起来的效果
查看>>
osd内的pg数量
查看>>
shell脚本与mysql交互方法汇总
查看>>