BZOJ-1086 [SCOI2005]王室联邦 (树分块)
2024-09-06 19:12:48
递归处理子树,把当前结点当作栈底,然后递归,回溯回来之后如果栈中结点数量到达某一个标准时,弹出栈中所有的元素分到一个块中,最后递归结束了如果栈中还有元素,那么剩下的这些元素放在新的块中
题目:BZOJ-1086
当块中元素大于B时,立即释放放入到一个新块中,省会可以直接用当前递归到的点,因为它的子节点一定是在栈中的。最后栈中剩下的部分是小于B的,所以可以直接加到上一个块中。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1010;
vector<int> G[N];
int n,B,st[N],sz = 0;
int block_cnt = 0,province[N],be[N];
void dfs(int u,int fa = -1){
int bottom = sz;//把当前结点当作栈底
for(int i = 0;i < G[u].size();i++){
int y = G[u][i];
if(y == fa)continue;
dfs(y,u);
if(sz - bottom >= B){//如果栈中元素大于B
block_cnt++;//块数++
while(sz != bottom){
be[st[sz--]] = block_cnt;
}
province[block_cnt] = u;
}
}
st[++sz] = u;//栈中加入该元素
}
int main(){
scanf("%d%d",&n,&B);
for(int i=1;i<n;i++){
int x,y;scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1);
while(sz)be[st[sz--]] = block_cnt;
printf("%d\n",block_cnt);
for(int i=1;i<=n;i++){
printf("%d ",be[i]);
}
puts("");
for(int i=1;i<=block_cnt;i++){
printf("%d ",province[i]);
}
puts("");
return 0;
}
最新文章
- 【原】js实现复制到剪贴板功能,兼容所有浏览器
- JQuery 判断浏览器及其版本
- PHOG特征
- MyEclipse自定义快捷键
- bash 常用操作
- 一个H5的3D滑动组件实现(兼容2D模式)
- 使用豆瓣的pypi源
- 第一次进div1了
- POJ 2075
- lintcode 中等题:N Queens N皇后问题
- Windows下TEX排版论文攻略—CTeX、JabRef使用心得
- iOS的沙箱目录和文件操作
- 【5】说说Laravel5的blade模板
- Linux学习2——文件与目录
- UIImageView控件
- 给 endv 取个好名字有赏!
- 201521123092《java程序设计》第九周学习总结
- AFNetWorking常用方法
- 【1】【leetcode-77】 组合
- android -------- 获取手机设备信息