BZOJ 1086:[SCOI2005]王室联邦(DFS树分块)
http://www.lydsy.com/JudgeOnline/problem.php?id=1086
题意:给出n个点的树,让你对树进行分块,每块的大小范围在[b, 3b]之间。
思路:一开始想着维护一个sz[u]代表以u为根的子树(不包括u本身)的大小,如果在范围之内就分成一块,但是这样写感觉一些细节上的东西没考虑清楚,WA了很久。
看了别人的做法:http://blog.csdn.net/popoqqq/article/details/42772237,很简洁。
大概是维护一个栈,每次dfs结束的时候入栈,在每次遍历子树之前标记一下当前的栈顶,当遍历子树的时候,如果当前的栈顶 - 之前的栈顶 >= b的话,就可以分成一块了。最后剩下的元素和最后一块连通。
结果的正确性:因为之前的子树大小加起来小于b,当前的子树大小小于b,所以当前的块大小小于2*b。最后剩余的元素小于b,最后的块小于2*b,因此小于3*b。
因为b小于n的,所以可以保证一定有答案。
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define N 1010
struct Edge {
int v, nxt;
} edge[N*];
int n, b, head[N], tot, belong[N], stk[N], top;
vector<int> ans; void Add(int u, int v) {
edge[tot] = (Edge) {v, head[u]}; head[u] = tot++;
edge[tot] = (Edge) {u, head[v]}; head[v] = tot++;
} void dfs(int u, int fa) {
int base = top; // 之前的栈顶
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(v == fa) continue;
dfs(v, u);
if(top - base >= b) {
ans.push_back(u);
while(base < top) belong[stk[top--]] = ans.size();
}
}
stk[++top] = u;
} int main() {
while(~scanf("%d%d", &n, &b)) {
memset(head, -, sizeof(head)); tot = top = ;
memset(belong, -, sizeof(belong));
for(int i = ; i < n; i++) {
int u, v; scanf("%d%d", &u, &v);
Add(u, v);
}
dfs(, -);
while(top) belong[stk[top--]] = ans.size(); // 最后元素
printf("%d\n", ans.size());
for(int i = ; i <= n; i++) printf("%d%c", belong[i], i == n ? '\n' : ' ');
for(int i = ; i < ans.size(); i++) printf("%d%c", ans[i], ans.size() - == i ? '\n' : ' ');
}
return ;
}
BZOJ 1086:[SCOI2005]王室联邦(DFS树分块)的更多相关文章
- [BZOJ 1086] [SCOI2005] 王室联邦 【树分块】
题目链接:BZOJ - 1086 题目分析 这道题要求给树分块,使得每一块的大小在 [B, 3B] 之间,并且可以通过一个块外的节点(块根)使得整个块联通. 那么我们使用一种 DFS,维护一个栈,DF ...
- BZOJ 1086 [SCOI2005]王室联邦 ——DFS
手把手教你树分块系列. 只需要记录一个栈,如果等于B的情况就弹栈,令省会为当前节点. 然后把待分块的序列不断上传即可. 考虑到有可能弹出不是自身节点的子树节点,所以记录一下当前的栈底. DFS即可 # ...
- 【块状树】BZOJ 1086: [SCOI2005]王室联邦
1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 826 Solved: ...
- Bzoj 1086: [SCOI2005]王室联邦(分块)
1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special Judge Submit: 1557 Solved: 9 ...
- BZOJ 1086: [SCOI2005]王室联邦
1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1399 Solved: ...
- bzoj 1086: [SCOI2005]王室联邦 (分块+dfs)
Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个不 ...
- [luoguP2325] [SCOI2005]王室联邦(树分块乱搞)
传送门 想了半小时,没什么思路.. 看了题解,是个叫做树分块的奇奇怪怪的操作.. 题解 树分块的研究 #include <cstdio> #include <cstring> ...
- BZOJ 1086: [SCOI2005]王室联邦 [树上分块]
portal 题意: 树分成若干块大小在$[s,3s]$之间,每块有一个根(可以不在块内),所有点到根路径上的点都必须在块内 据说这是一个保证了块大小直径个数的科学分块方法,貌似只有本题有用 我错了 ...
- BZOJ1086 [SCOI2005]王室联邦(树分块)
把树的结点分块,块内结点连通且个数[b,3b]. 一遍DFS,维护一个栈,设置一个虚拟栈底以保证连通,递归返回时判断栈内元素个数是否大于等于b,是则划分为一个块,最后剩下的与最后一个块划分在一起. h ...
- bzoj 1086 [SCOI2005]王室联邦——思路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1086 于是去看了题解. 要回溯的时候再把自己加进栈里判断.这样才能保证剩下的可以通过自己连到 ...
随机推荐
- TASM 5.0 安装及使用教程
安装TASM 5.0很简单,您只需要下载本站[相关工具]中的"TASM50.zip"文件,解压后在Windows9x/NT下执行"INSTALL.EXE"即可开 ...
- WPF 使用Propereties:Resources.resx里面的资源
<Window x:Class="Wpf180706.Window7" xmlns="http://schemas.microsoft.com/win ...
- jquery属性过滤器
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Hermite曲线插值
原文 Hermite Curve Interpolation Hermite Curve Interpolation Hamburg (Germany), the 30th March 1998. W ...
- WPF最大化避免覆盖任务栏
原文:WPF最大化避免覆盖任务栏 WPF当窗体WindowStyle=”None”时,最大化会覆盖掉任务栏.如何解决这个问题呢? 我在Google里面搜到一篇文章,要用到Win32 API,通过让WP ...
- Window 下 MySQL 环境的安装
Window 下 MySQL 环境的安装 简介: MySQL 是最流行的关系型数据库管理系统,在WEB应用方面 MySQL 是最好的RDBMS(Relational Database Manageme ...
- Android 开发相关
1.app下载更新 https://git.oschina.net/lwngreat/UpdateHelper
- HTML特殊编码转换
var encoded = ""'&<>¡¢£¤" + "¥¦§¨©ª«¬®" + "¯°±²³´µ¶·" ...
- Win10《芒果TV》商店版更新v3.1.4.0:适配Xbox手柄B键后退、手机支持暗色主题不伤眼
在双十一全球剁手节.光棍节欢庆之际,<芒果TV>UWP版迅速更新v3.1.4版,适配Xbox手柄B键全局后退,支持手机切换暗色主题,优化并解决启动卡顿等问题. 芒果TV UWP V3.1. ...
- lvcreate命令
lvcreate Command Examples on Linux : 1. The following command creates a logical volume 15 gigabytes ...