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. Scapy实现SYN泛洪攻击

    一.实验说明 1.实验介绍 本次实验将使用python3版本的Scapy--Scapy3k来实现一个简单的DDos,本次实验分为两节,本节将学习如何使用Scapy3k来实现SYN泛洪攻击. 2.知识点 ...

  2. string类的简洁版实现

    说是原创,差不多算是转载了,我也是看了好多大牛的写法,大牛的建议,自己加一总结,形成代码: 实现一个简洁版的string类,我觉得,下面的也够了:另外需要参见另外的写法: http://blog.cs ...

  3. NetFPGA Demo ——reference_router_nf1_cml

    NetFPGA Demo --reference_router_nf1_cml 前言 本博文主要介绍了reference_router_nf1_cml该demo的一路运行,以及一路上艰难跑通遇到的坑. ...

  4. Tornado 网站demo 一

    web服务器的工作过程 创建 listen socket, 在指定的监听端口, 等待客户端请求的到来 listen socket 接受客户端的请求, 得到 client socket, 接下来通过 c ...

  5. ajax的四种type类型

    1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数据,不会影响资源的内容,即该请求不会产生副作用.无论进行多少次操 ...

  6. centos 6.5安装并配置mysql

    折腾了半天终于把mysql安装并配置好了,以下是安装步骤和遇到问题的解决方式 1.查看机器上是否已经安装了mysql或其相关项 # yum list installed | grep mysql如果安 ...

  7. Ubuntu命令行连接WPA/WPA2无线网线

    一,连接无加密无线网络zhang:sudo ip link set wlan0 up sudo iw dev wlan0 connect zhangsudo dhclient wlan0 二,连接WP ...

  8. Mysql必须知道的知识

    最近在准备面试,所以也整理了一些Mysql数据库常用的知识,供大家参考. 1.MySQL的复制原理以及流程 (1).复制基本原理流程 1. 主:binlog线程--记录下所有改变了数据库数据的语句,放 ...

  9. hadoop大数据技术架构详解

    大数据的时代已经来了,信息的爆炸式增长使得越来越多的行业面临这大量数据需要存储和分析的挑战.Hadoop作为一个开源的分布式并行处理平台,以其高拓展.高效率.高可靠等优点越来越受到欢迎.这同时也带动了 ...

  10. Python内置函数(11)——complex

    英文文档: class complex([real[, imag]]) Return a complex number with the value real + imag*1j or convert ...