BZOJ 1086: [SCOI2005]王室联邦
1086: [SCOI2005]王室联邦
Time Limit: 10 Sec Memory Limit: 162 MBSec Special Judge
Submit: 1399 Solved: 830
[Submit][Status][Discuss]
Description
“余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成
员来管理。他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个不同的城市之间有且仅有一条
直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个
城市。每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经
过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。一个城市可以作为多个省的省会。聪明的
你快帮帮这个国王吧!
Input
第一行包含两个数N,B(1<=N<=1000, 1 <= B <= N)。接下来N-1行,每行描述一条边,包含两个数,即这
条边连接的两个城市的编号。
Output
如果无法满足国王的要求,输出0。否则输出数K,表示你给出的划分方案中省的个数,编号为1..K。第二行输
出N个数,第I个数表示编号为I的城市属于的省的编号,第三行输出K个数,表示这K个省的省会的城市编号,如果
有多种方案,你可以输出任意一种。
Sample Input
1 2
2 3
1 8
8 7
8 6
4 6
6 5
Sample Output
2 1 1 3 3 3 3 2
2 1 8
HINT
Source
DFS每一个点,先递归子树,然后拿到子树传回的该子树中的未分组点。对所有子树的传回点合并,每每够了B个就分一块。最后把自己加入未分组点队列,传回上层。这是分块方法的一种叙述,但显然不能这么写是吧,2333。
用一个栈保存未分组的点,每次DFS一个点先记录下此时的栈顶位置,然后递归子树,每每当前栈顶到记录栈顶元素个数超过B个,就把这一段分为一块。这一段一定都是在当前点的子树里,且和当前点相邻。最后把当前点压入栈顶,返回上层即可。
这种分块的方法貌似也经常用在树上莫队等问题中。
#include <bits/stdc++.h>
const int siz = ;
char buf[siz], *bit = buf;
inline int nextInt (void) {
register int ret = ;
register int neg = ;
while (*bit < '')
if (*bit++ == '-')
neg ^= true;
while (*bit >= '')
ret = ret* + *bit++ - '';
return neg ? -ret : ret;
}
const int maxn = + ;
int n;
int m;
int tot;
int cnt;
int top;
int hd[maxn];
int nt[maxn];
int to[maxn];
int stk[maxn];
int bel[maxn];
int cap[maxn];
void divid (int u, int f) {
int bot = top;
for (register int i = hd[u]; ~i; i = nt[i])
if (to[i] != f) {
divid (to[i], u);
if (top - bot >= m) {
cap[++cnt] = u;
while (top != bot)
bel[stk[top--]] = cnt;
}
}
stk[++top] = u;
}
signed main (void) {
fread (buf, , siz, stdin);
n = nextInt ();
m = nextInt ();
memset (hd, -, sizeof (hd)), tot = ;
for (register int i = ; i < n; ++i) {
int x = nextInt ();
int y = nextInt ();
nt[tot] = hd[x]; to[tot] = y; hd[x] = tot++;
nt[tot] = hd[y]; to[tot] = x; hd[y] = tot++;
}
divid (, -);
while (top > )
bel[stk[top--]] = cnt;
printf ("%d\n", cnt);
for (register int i = ; i < n; ++i)
printf ("%d ", bel[i]);
printf ("%d\n", bel[n]);
for (register int i = ; i < cnt; ++i)
printf ("%d ", cap[i]);
printf ("%d\n", cap[cnt]);
}
@Author: YouSiki
BZOJ 1086: [SCOI2005]王室联邦的更多相关文章
- 【块状树】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] 王室联邦 【树分块】
题目链接:BZOJ - 1086 题目分析 这道题要求给树分块,使得每一块的大小在 [B, 3B] 之间,并且可以通过一个块外的节点(块根)使得整个块联通. 那么我们使用一种 DFS,维护一个栈,DF ...
- bzoj 1086: [SCOI2005]王室联邦 (分块+dfs)
Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个不 ...
- bzoj 1086 [SCOI2005]王室联邦——思路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1086 于是去看了题解. 要回溯的时候再把自己加进栈里判断.这样才能保证剩下的可以通过自己连到 ...
- BZOJ 1086: [SCOI2005]王室联邦 [树上分块]
portal 题意: 树分成若干块大小在$[s,3s]$之间,每块有一个根(可以不在块内),所有点到根路径上的点都必须在块内 据说这是一个保证了块大小直径个数的科学分块方法,貌似只有本题有用 我错了 ...
- BZOJ 1086 [SCOI2005]王室联邦 ——DFS
手把手教你树分块系列. 只需要记录一个栈,如果等于B的情况就弹栈,令省会为当前节点. 然后把待分块的序列不断上传即可. 考虑到有可能弹出不是自身节点的子树节点,所以记录一下当前的栈底. DFS即可 # ...
- 1086: [SCOI2005]王室联邦
1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1554 Solved: ...
- 【BZOJ】1086: [SCOI2005]王室联邦
http://www.lydsy.com/JudgeOnline/problem.php?id=1086 题意:n个点的树,要求分块,使得每一块的大小在[b, 3b]内且块与某个点形成的块是连通的(某 ...
随机推荐
- C++的单例模式与线程安全单例模式(懒汉/饿汉)
1 教科书里的单例模式 我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实 ...
- 关于Hibernate 的数据库配置
<hibernate-configuration> <session-factory name="mySessionFactory"> ...
- .NET并行编程实践(一:.NET并行计算基本介绍、并行循环使用模式)
阅读目录: 1.开篇介绍 2.NET并行计算基本介绍 3.并行循环使用模式 3.1并行For循环 3.2并行ForEach循环 3.3并行LINQ(PLINQ) 1]开篇介绍 最近这几天在捣鼓并行计算 ...
- Oracle索引梳理系列(七)- Oracle唯一索引、普通索引及约束的关系
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- 【Linux学习】如何了解一个陌生的命令?
如何了解一个陌生的命令? 有一些命令可以用来了解某个命令本身的情况,比如这个命令的绝对路径. $which ls which 在默认路径中搜索命令,返回该命令的绝对路径. $whereis ls wh ...
- Linux--shell脚本之正则表达式
一.正则表达式的概念及特点: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑.规 ...
- 关于ActionBar
添加ActionBar: Android 3.0(API 11)(不含API11)以下的版本中,如果需要活动有ActionBar,需要让活动继承ActionBarActivity类,并且在Manife ...
- EF 数据库连接字符串-集成安全性访问 SQL Server
使用 Windows 集成安全性访问 SQL Server 如果您的应用程序运行在基于 Windows 的 Intranet 上,则也许可以将 Windows 集成身份验证用于数据库访问.集成安全性使 ...
- js parseInt和map函数
今天看了一个js的题目["1","2","3"].map(parseInt),看到后脑海中浮现的答案是[1,2,3],但是看到正确答案后蒙了 ...
- C++11 之 并发编程 (一)
未来芯片制造,如果突破不了 5nm 极限,则 CPU 性能的提升,可能会依赖于三维集成技术,将多个 CPU 核集成在一起,使得多核系统越来越普遍. 以前的 C++ 多线程,一是受限于平台,多借助于封装 ...