1086: [SCOI2005]王室联邦

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
Submit: 1554  Solved: 933
[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

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

HINT

 

Source

大神们都一句话带过。

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

整理一下,发给大家。

先说一个问题:

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

在左儿子的子树中搜得的节点数是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!而且最后被划分出来的省一定和最后无家可归的节点中的某一个相邻!那么考虑什么时候会出现无解呢?答案就是我们找不到“上一个被划分出的省”

#include<cstdio>
using namespace std;
const int N=1e4+;
struct node{
int v,next;
}e[N<<];
int n,B,top,tot,cnt,head[N],belong[N],root[N],stack[N];
void add(int x,int y){
e[++tot].v=y;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].next=head[y];head[y]=tot;
}
void dfs(int x,int fa){
int bottom=top;
for(int i=head[x];i;i=e[i].next){
if(e[i].v!=fa){
dfs(e[i].v,x);
if(top-bottom>=B){
root[++cnt]=x;
for(;top!=bottom;top--) belong[stack[top]]=cnt;
}
}
}
stack[++top]=x;
}
int main(){
scanf("%d%d",&n,&B);
for(int i=,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y);
dfs(,);
for(;top;top--) belong[stack[top]]=cnt;
printf("%d\n",cnt);
for(int i=;i<=n;i++) printf("%d ",belong[i]);putchar('\n');
for(int i=;i<=cnt;i++) printf("%d ",root[i]);putchar('\n');
return ;
}

1086: [SCOI2005]王室联邦的更多相关文章

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

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

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

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

  3. Bzoj 1086: [SCOI2005]王室联邦(分块)

    1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special Judge Submit: 1557 Solved: 9 ...

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

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

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

    http://www.lydsy.com/JudgeOnline/problem.php?id=1086 题意:n个点的树,要求分块,使得每一块的大小在[b, 3b]内且块与某个点形成的块是连通的(某 ...

  6. [BZOJ 1086] [SCOI2005] 王室联邦 【树分块】

    题目链接:BZOJ - 1086 题目分析 这道题要求给树分块,使得每一块的大小在 [B, 3B] 之间,并且可以通过一个块外的节点(块根)使得整个块联通. 那么我们使用一种 DFS,维护一个栈,DF ...

  7. bzoj 1086 [SCOI2005]王室联邦——思路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1086 于是去看了题解. 要回溯的时候再把自己加进栈里判断.这样才能保证剩下的可以通过自己连到 ...

  8. BZOJ 1086: [SCOI2005]王室联邦 [树上分块]

    portal 题意: 树分成若干块大小在$[s,3s]$之间,每块有一个根(可以不在块内),所有点到根路径上的点都必须在块内 据说这是一个保证了块大小直径个数的科学分块方法,貌似只有本题有用  我错了 ...

  9. BZOJ 1086 [SCOI2005]王室联邦 ——DFS

    手把手教你树分块系列. 只需要记录一个栈,如果等于B的情况就弹栈,令省会为当前节点. 然后把待分块的序列不断上传即可. 考虑到有可能弹出不是自身节点的子树节点,所以记录一下当前的栈底. DFS即可 # ...

随机推荐

  1. 一个非常标准的连接Mysql数据库的示例代码

    一.About Mysql 1.Mysql 优点 体积小.速度快.开放源码.免费 一般中小型网站的开发都选择 MySQL ,最流行的关系型数据库 LAMP / LNMP Linux作为操作系统 Apa ...

  2. c# 动态实例化一个泛型类

    动态实例化一个类,比较常见,代码如下 namespace ConsoleApp2 { public class MyClass { } } Type classType = Type.GetType( ...

  3. 构建微服务开发环境1————如何安装JDK

    [内容指引] 下载JDK: Mac系统安装JDK: Mac系统配置环境变量: Windows系统安装JDK: Windows系统配置环境变量. 一.下载JDK 1.访问Oracle官网 http:// ...

  4. Beta冲刺合集

    Beta冲刺序列: Beta凡事预则立 :Beta No.0 Beta冲刺Day1:Beta No.1 Beta冲刺Day2:Beta No.2 Beta冲刺Day3:Beta No.3 Beta冲刺 ...

  5. Beta冲刺NO.2

    Beta冲刺 第二天 1.昨天的问题 由于前面的冲刺留下的问题很多,而且混乱的代码给我们接下来的完善工作带来了巨大的困难. 2. 今天解决的进度 潘伟靖: 1.对代码进行了review 2.为系统增加 ...

  6. class AClass<E extends Comparable>与class AClass<E extends Comaprable<E>>有什么区别?

    new ArrayList<>()与new ArrayList()一样 都是为了做限定用的 如果不了解你可以看API 这个Comparable里面有一个方法compareTo(T o) 如 ...

  7. 利用python实现简单邮件功能

    #!/usr/bin/env python # -*- coding:utf-8 -*- import smtplib from email.utils import formataddr from ...

  8. 大数据技术Hadoop笔试题

    Hadoop有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上.以下是由应届毕业生网小编J.L为您整理推荐的面试笔试题目和经验,欢迎参考阅读. 单项选择题 1. 下面哪个程序负责 H ...

  9. 常用Mysql数据库操作语句

    用户管理: 1.新建用户: 语法msyql>CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明: username - 你将创建 ...

  10. JAVA_SE基础——43.抽象类

    高手勿喷~ 抽象类:当定义一个类时,常常需要定义一些方法来描述该类的行为特征,但有时这些方法的实现方式是无法确定的.例如定义Animal类时,shout()方法用于表示动物的叫声,但是针对不同的动物, ...