「日常训练&知识学习」树的分块(王室联邦,HYSBZ-1086)
题意与分析
这题的题意就是树分块,更具体的看题目(中文题)。
学习这一题是为了树的分块,为树上莫队做铺垫。
参考1:https://blog.csdn.net/LJH_KOQI/article/details/52326103
参考2:https://blog.csdn.net/popoqqq/article/details/42772237
注意到题目要求某块区域所有的点到根的路径上的点都属于该区域。因此不能够暴力地去dfs,每找到\(B\)个分一块是不可取的,因为无法保证联通性(一颗子树的下半截和另一棵子树的上半截组成一块)。因此,我们需要尽可能地从底部往上去组织块(Block),“每棵子树较深的部分自己成块,然后靠近根的部分组成一个大块”。
因此这么做:对于一个点\(x\),以初次访问它时,栈的栈顶作为相对栈底,每遍历完它的一个子节点所在的子树(先遍历完),判断此时栈顶减去相对栈底得到的元素个数是否\(\ge B\),如果成立,那么弹栈至相对栈顶。当访问完所有子节点要回溯到x的父节点时,再把x压入栈。这样一来,一个子树深搜过后,子树内地未分块节点不会超过B,而搜索子树前的未分块节点数也不会超过b,从而每块不会超过\(2B\);最后dfs结束时剩余的未组成块的节点个数也不会超过b,从而最后一块不会超过\(3B\),把它们归到最后一个块就可以了。这种分块方法就可以保证连通性和块的大小了。
代码
/*
* Filename: hysbz1086.cpp
* Date: 2018-11-13
*/
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define PB push_back
#define MP make_pair
#define fi first
#define se second
#define rep(i,a,b) for(repType i=(a); i<=(b); ++i)
#define per(i,a,b) for(repType i=(a); i>=(b); --i)
#define ZERO(x) memset(x, 0, sizeof(x))
#define MS(x,y) memset(x, y, sizeof(x))
#define ALL(x) (x).begin(), (x).end()
#define QUICKIO \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
#define DEBUG(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
using namespace std;
typedef long long ll;
typedef int repType;
const int MAXN=1005;
vector<int> G[MAXN];
int stk[MAXN],top=0;
int root[MAXN],cnt=0;
int belong[MAXN];
int n,b;
void dfs(int now, int pre)
{
int bottom=top;
rep(i,0,int(G[now].size())-1) if(G[now][i]!=pre)
{
dfs(G[now][i],now);
if(top-bottom>=b)
{
root[++cnt]=now;
while(top!=bottom)
belong[stk[top--]]=cnt;
}
}
stk[++top]=now;
}
int
main()
{
QUICKIO
cin>>n>>b;
rep(i,1,n-1)
{
int u,v; cin>>u>>v;
G[u].PB(v);
G[v].PB(u);
}
dfs(1,0);
while(top) // the last block
belong[stk[top--]]=cnt;
cout<<cnt<<endl;
rep(i,1,n)
cout<<belong[i]<<char(i==n?'\n':' ');
rep(i,1,cnt)
cout<<root[i]<<char(i==cnt?'\n':' ');
return 0;
}
「日常训练&知识学习」树的分块(王室联邦,HYSBZ-1086)的更多相关文章
- 「日常训练&知识学习」树的直径(POJ-1849,Two)
题意 一个城市由节点和连接节点的街道组成,街道是双向的. 此刻大雪覆盖了这个城市,市长确定了一些街道要将它们清扫干净,这些街道保证所有的节点可以通过它们连通而且街道数目尽可能小. 现有两台相同的扫雪机 ...
- 「日常训练&知识学习」单调栈
这几天的知识学习比较多,因为时间不够了.加油吧,为了梦想. 这里写几条简单的单调栈作为题解记录,因为单调栈的用法很简单,可是想到并转化成用这个需要一些题目的积淀. 相关博客参见:https://blo ...
- 「日常训练&知识学习」莫队算法(二):树上莫队(Count on a tree II,SPOJ COT2)
题意与分析 题意是这样的,给定一颗节点有权值的树,然后给若干个询问,每次询问让你找出一条链上有多少个不同权值. 写这题之前要参看我的三个blog:Codeforces Round #326 Div. ...
- 「国庆训练&知识学习」图的最大独立集与拓展(Land of Farms,HDU-5556)
题意 一个\(N*M\)的矩阵,其中"."代表空地,"0-9"代表古代建筑,我们如果选择了一个编号的古代建筑想要建立,那么对应就要将全部该编号的建筑建立起来,如 ...
- 「日常训练」Caterpillar(POJ-3310)
题意与分析 一条很有趣的题目.给一个无向图,问它是否无环,且可以在上面找到一条线,使所有的顶点要么在线上要么不在线上但在与线相连的边上. 那么首先要确定所有点联系在一起.这个可以同判环一起处理:如果建 ...
- 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)
题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...
- 「2019-8-13提高模拟赛」树 (tree)
传送门 Description 你有一个 \(n\)个点的树,第 \(i\)个点的父亲是\(p_i\).每个点有一个权值 \(t_i\) 和一个颜色黑或者白.所有点一开始都是白色. 你要进行 \(m\ ...
- 「日常训练」Duff in the Army (Codeforces Round #326 Div.2 E)
题意(CodeForces 588E) 给定一棵\(n\)个点的树,给定\(m\)个人(\(m\le n\))在哪个点上的信息,每个点可以有任意个人:然后给\(q\)个询问,每次问\(u\)到\(v\ ...
- 「日常训练」 Fire!(UVA-11624)
与其说是训练不如说是重温.重新写了Java版本的代码. import java.util.*; import java.math.*; import java.io.BufferedInputStre ...
随机推荐
- [JSOI2016]最佳团体
嘟嘟嘟 01分数规划+树形背包. 然后就没了. 结果我调了半天,原因还是树形背包不熟练. 我是用dfs序求的,转化的时候,是dp[i][j]转化到dp[i + 1][j + 1]或dp[i +siz[ ...
- “ping某个IP地址,如果ping不通则在dos窗口或弹出MsgBox提示原因”的批处理bat命令
“ping某个IP地址,如果ping不通则在dos窗口提示原因”的批处理bat命令 @echo off&setlocal enabledelayedexpansion title Ping检测 ...
- [转]HTTP报文接口及客户端和服务器端交互原理
1. 协议 a. TCP/IP整体构架概述 TCP/IP协议并不完全符合OSI的七层参考模型.传统的开放式系统互连参考模型,是一种通信协议的7层抽象的参考模型,其中每一层执行某一特定任务.该模型的目的 ...
- CSU - 1224 ACM小组的古怪象棋
传送门: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1224 1224: ACM小组的古怪象棋 Lime Limit: 1 Sec ...
- HDU 2021 发工资咯:)(最水贪心)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2021 发工资咯:) Time Limit: 2000/1000 MS (Java/Others) ...
- STM32F103 ucLinux开发之四(内核启动后的调试)
Stm32-uclinux启动后的调试 1. 修改__pfn_to_page使得能够启动 根据STM32F103 ucLinux开发之三(内核启动后不正常)的描述,内核无法启动是选择了平板内存模式后 ...
- Java IP白名单相关工具类
关于设置IP白名单相关的一些方法,整理,记录了一下. package com.tools.iptool; import java.util.ArrayList; import java.util.Ha ...
- Eclipse 中打开选中文件/文件夹所在目录
习惯了使用VS中的 ”通过右键打开选中文件/文件夹在电脑中的目录”功能后, 当切换到Eclipse环境后,发现居然找不到这个功能, 虽可以通过右键文件属性,看到文件路径,复制路径然后在资源管理器中打开 ...
- 『ACM C++』 PTA 天梯赛练习集L1 | 050-51
加油加油,努力刷题 ------------------------------------------------L1-050------------------------------------ ...
- 【模板】BM算法(找线性规律万能模板)
(1) n是指要找该数列的第n项. (2) 往vec中放入该数列前几项的值,越多越精确. #include<set> #include<cmath> #include<v ...