博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】1086: [SCOI2005]王室联邦
阅读量:6773 次
发布时间:2019-06-26

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

【题意】给定n个点的树,要求划分成若干大小为[B,3B]的块,满足一个块加上一个核心点后连通,求方案。n<=1000。

【算法】树分块

【题解】参考: 讲得很详细了,就不必听我口胡了。。。

树分块算法的起源?用这道题的树分块算法可以实现将一棵树划分成若干[B,3B]的块。

DFS过程中用栈记录,扫描到点x时记录top作为当前子树x的栈底(下面的点不能取)。

如果某棵子树扫描后有>=B个点,那么直接构成一块。

如果两棵子树扫描后才有>=B个点,那么这一块一定在[B,2B)之间,也构成一块。

最后剩余的点加入最后一块,至多会使最后一块变成3B。

复杂度O(n)。

#include
#include
#include
using namespace std;const int maxn=1010;int n,B,first[maxn],s[maxn],st[maxn],belong[maxn],tot=0,cnt=0,ans=0,top=0;struct edge{
int v,from;}e[maxn*2];void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}void dfs(int x,int fa){ int lim=top; for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){ dfs(e[i].v,x); if(top-lim>=B){ ans++;s[ans]=x; while(top>lim)belong[st[top--]]=ans; } } st[++top]=x;}int main(){ scanf("%d%d",&n,&B); for(int i=1;i
View Code

 

转载于:https://www.cnblogs.com/onioncyc/p/8571337.html

你可能感兴趣的文章
(待写)五大常用算法:分治、动态规划、贪心、回溯和分支界定
查看>>
C++ - memset的效率和源码分析
查看>>
【UIKit】UITableView 1
查看>>
[HeadFirst-HTMLCSS学习笔记][第十三章表格]
查看>>
2017-2018-2上课课程
查看>>
linux文件删除原理
查看>>
python 模块
查看>>
(5)连续非周期信号的傅里叶变换(频谱) & 周期信号的傅里叶变换
查看>>
poj 1422 Air Raid (二分匹配)
查看>>
Apache Storm技术实战之2 -- BasicDRPCTopology
查看>>
随机数生成器
查看>>
makefile学习笔记
查看>>
Computer Science - CS:APP - 2.1 信息存储
查看>>
【shell】sed指定追加模式空间的次数
查看>>
8. Security-oriented operating systems (面向安全的操作系统 5个)
查看>>
【转】cocos2dx 3.x 集成protobuf
查看>>
ABAP JSON转换
查看>>
mac 下获取 os x 的系统版本,使用 oc cocoa
查看>>
12.1动态内存与智能指针
查看>>
python和C语言混编的几种方式
查看>>