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

8 2
1 2
2 3
1 8
8 7
8 6
4 6
6 5

Sample Output

3
2 1 1 3 3 3 3 2
2 1 8

题解(转载)

->原文地址<-

大神们都一句话带过。

在网上扒了老长时间,才领悟。

整理一下,发给大家。

先说一个问题:

如果在当前节点,其有两个儿子。

在左儿子的子树中搜得的节点数是$a-1$的话,这时候我们去搜右儿子,不妨假设右儿子为根的子树是一条长为$10000$的链。

那么显然最下面的叶节点跟左儿子代表的子树是在同一块中的,这显然碎成渣了。

所以每一次搜到一个节点,我们都要把当前的栈的指针当做该节点的相对栈底,这样的话就能避免这个问题。

首先以任意节点为根$DFS$,$DFS$的任务是解决以当前节点为根的子树(不包括当前节点)中的节点的归属,并汇报不知道去向何方者。

具体做法是:

对于每个正在处理的节点$v$,定义一个等待序列,扫一遍它的孩子。在扫的时候,假设当前$for$循环正在处理的是孩子$u$,$DFS(u)$,然后把传回来的等待序列加到$v$的等待序列中。如果$v$的等待序列节点数超过了$B$,那么就让等待队列中的节点组成一个省,省会是$v$,但$v$不划入那个省中。最后,$for$循环结束,把$v$加入到等待序列中,$return$。在主函数中接收$DFS$的返回值,若等待序列为空,皆大欢喜;但事实上,等待序列不可能为空。

那么等待序列中的节点数一定不超过$B + 1$,怎么办?答案就是放在上一个被划分出的省中去,那么上一个被划分出的省一定$<=2B - 1$,而现在最后无家可归的节点数一定$<= B + 1$,所以放在上一个被划分出的省中去节点数一定不超过$3B$!而且最后被划分出来的省一定和最后无家可归的节点中的某一个相邻!那么考虑什么时候会出现无解呢?答案就是我们找不到“上一个被划分出的省”

 //It is made by Awson on 2017.9.28
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define sqr(x) ((x)*(x))
using namespace std;
const int N = ;
void read(int &x) {
char ch; bool flag = ;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || ); ch = getchar());
for (x = ; isdigit(ch); x = (x<<)+(x<<)+ch-, ch = getchar());
x *= -*flag;
} int n, b, u, v;
int sta[N+], top;
int cnt, belong[N+], root[N+];
struct tt {
int to, next;
}edge[*N+];
int path[N+], tot; void add(int u, int v) {
edge[++tot].to = v;
edge[tot].next = path[u];
path[u] = tot;
}
void dfs(int u, int fa) {
int bot = top;
for (int i = path[u]; i; i = edge[i].next)
if (edge[i].to != fa) {
dfs(edge[i].to, u);
if (top-bot >= b) {
root[++cnt] = u;
while (top != bot) belong[sta[top--]] = cnt;
}
}
sta[++top] = u;
}
void work() {
read(n), read(b);
for (int i = ; i < n; i++) {
read(u), read(v);
add(u, v); add(v, u);
}
dfs(, );
while (top) belong[sta[top--]] = cnt;
printf("%d\n", cnt);
for (int i = ; i <= n; i++) printf("%d ", belong[i]);
printf("\n");
for (int i = ; i <= cnt; i++) printf("%d ", root[i]);
printf("\n");
}
int main() {
work();
return ;
}

[SCOI 2005]王室联邦的更多相关文章

  1. BZOJ1086 [SCOI2005]王室联邦 【dfs + 贪心】

    题目 "余"人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成 员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两 ...

  2. BZOJ 1086: [SCOI2005]王室联邦

    1086: [SCOI2005]王室联邦 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1399  Solved: ...

  3. 【BZOJ-1086】王室联邦 分块 + 块状树

    1086: [SCOI2005]王室联邦 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1094  Solved: ...

  4. BZOJ1086 [SCOI2005]王室联邦

    Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成 员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个 ...

  5. 【块状树】BZOJ 1086: [SCOI2005]王室联邦

    1086: [SCOI2005]王室联邦 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 826  Solved:  ...

  6. 【BZOJ】【1086】 【SCOI2005】王室联邦

    树分块 orz vfk && PoPoQQQ http://vfleaking.blog.163.com/blog/static/174807634201231684436977/ h ...

  7. 1086: [SCOI2005]王室联邦

    1086: [SCOI2005]王室联邦 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1554  Solved: ...

  8. bzoj 1086: [SCOI2005]王室联邦 (分块+dfs)

    Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个不 ...

  9. [SCOI2005]王室联邦(构造)

    “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理. 他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个不同的城市之间有且仅有一 ...

随机推荐

  1. c语言第一次作业——输入与输出格式

    一.PTA实验作业 1.温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验代码 ...

  2. 亚马逊的PuTTY连接AWS出现network error connection refused,终极解决方案。

    使用PuTTY连接AWS的时候,一直出现network error connection refused.百度了这个问题,大家都说是SSH要设置成22.但是我已经设置过了,为什么还是遇到这个问题呢? ...

  3. hdu 3642 Get The Treasury

    Get The Treasury http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Othe ...

  4. mycat入门_介绍与安装

    利用闲暇时间接触了下mycat. 一.介绍 1.概述: 国内最活跃的.性能最好的开源数据库中间件,可以理解为数据库和应用层之间的一个代理组件. 2.作用: 读写分离.分表分库.主从切换. 3.原理: ...

  5. java异常常见面试问题

    java异常常见面试问题 一.java异常的理解 异常主要是处理编译期不能捕获的错误.出现问题时能继续顺利执行下去,而不导致程序终止,确保程序的健壮性. 处理过程:产生异常状态时,如果当前的conte ...

  6. Clover3(可以让Windows Explorer像浏览器一样有标签页)

    这不是广告!!! 下载地址:http://cn.ejie.me/ 效果图:

  7. Centos7安装openvpn及客户端配置

    1.openvpn介绍 VPN直译就是虚拟专用通道,是提供给企业之间或者个人与公司之间安全数据传输的隧道,使用OpenSSL加密库中的SSLv3/TLSv1协议函数库. 目前OpenVPN能在Sola ...

  8. Python内置函数(24)——set

    英文文档: class set([iterable]) Return a new set object, optionally with elements taken from iterable. s ...

  9. Step by Step 真正从零开始,TensorFlow详细安装入门图文教程!帮你完成那个最难的从0到1

    摘要: Step by Step 真正从零开始,TensorFlow详细安装入门图文教程!帮你完成那个最难的从0到1 安装遇到问题请文末留言. 悦动智能公众号:aibbtcom AI这个概念好像突然就 ...

  10. matlab 对tif数据高程图的处理分析

    temp=z(101:2200,101:2200) 根据图像属性可得此为2300*2300的tif图像,由于需要将其划分为9宫格,所以begin点设置为101,end点设置为2200,temp转化为可 ...