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. Redux----Regular的Redux实现整理

      Regular的Redux实现整理 什么问题? 组件的树形结构决定了数据的流向,导致的数据传递黑洞 怎么解决? 所有组件都通过中介者传递共享数据 方案: 中介者: (function create ...

  2. 《团队-Android手机便签-项目进度》

    首先想提个小意见,结对编程那边还有些问题需要处理,这个时候就催团队进度是不是不太好,至少应该让我们把结对处理完是吧.但是作业终究是作业,布置了就得做,我们只得匆匆忙忙画了个界面,功能什么的根本没来得及 ...

  3. Alpha冲刺Day4

    Alpha冲刺Day4 一:站立式会议 今日安排: 我们把项目大体分为四个模块:数据管理员.企业人员.第三方机构.政府人员.完成了数据库管理员模块.因企业人员与第三方人员模块存在大量的一致性,故我们团 ...

  4. 视频聊天插件:AnyChat使用攻略之iOS开发指南

    AnyChat使用攻略之iOS开发指南 这套攻略主要指导刚开始使用AnyChat SDK For iOS的同学,快速搭建SDK环境,和实现音视频开发流程. (需要工程案例文件可联系我们) 在iOS平台 ...

  5. pymysql 多字段插入

    d = {'name':'alx','age':18,'pp':11,'cc':12} sql = '''insert into xx(%s) value(%s)''' key_list = [] v ...

  6. 再一次, 不要使用(include/require)_once

    本文地址: http://www.laruence.com/2012/09/12/2765.html 最近关于apc.include_once_override的去留, 我们做了几次讨论, 这个APC ...

  7. NodeJs实现自定义分享功能,获取微信授权+用户信息

    最近公司搞了个转盘抽奖的运营活动,入口放在了微信公众号里,好久没碰过微信了,刚拾起来瞬间感觉有点懵逼....似乎把之前的坑又都重新踩了一遍,虽然过程曲折,不过好在顺利完成了,而且印象也更加深刻了,抽时 ...

  8. Tomcat8.0 配置环境

    (1)首先安装JDk 下载jdk进行安装后进行配置环境 新增一个Java_Home的变量复制本地安装目录的路径:eg:C:\Program Files (x86)\Java\jdk1.8.0_141\ ...

  9. Python系列-python函数

    函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函数,这 ...

  10. mysql解压缩版本的安装、初始化等

    https://dev.mysql.com/doc/refman/5.7/en/windows-install-archive.html 启动或者暂停mysql服务: https://dev.mysq ...