题意:国王想把他的国家划分成若干个省。他的国家有n个城市,是一棵树,即n-1条边,编号为1..n。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个城市。每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。一个城市可以作为多个省的省会。输出有多少个省会,每个城市属于哪个省会,每个省的省会。

思路:暂时先不管省会应该在哪的问题,其实就是要对树进行分块,每块必须有b~3b的点。

  那么如何分块?按常理,只要搜索满b个点就立刻进行组块,而且块中的点最好是连通的,如若不巧,非连通,一会再说,能解决。由于要尽量使得所分的块是连通的,那么可以用DFS的回溯,将回溯过程收集的点装进stack,一般来说,任意一个点为根的子树中的所有点都是在stack中是连在一块的(因为先收集完孩子才会收集到自己,所以这是肯定的)。

  收集完这个回溯序列有什么用?分块其实可以从里面分出来,只是不能随便就按照b个点就分一块,这样子可能会不连通。但是可以利用“以任意一点为根的子树中所有点在stack中肯定是相连的”这个特点,如果遍历到某个点x,它的某1个分叉中的点已经够b个了,那就组成一块;如果这一分叉不够b个,那么可以跟另一分叉组成一块,这样子虽然是不连通的,但是没有关系,只要省会设置在当前点x,不就连通了?不够点数的分叉都是可以组成1块,注意将一棵子树遍历完了,才能考虑将这个子树中的点分块。

  如果stack中仍有剩下的点,肯定是不足b个,那么可以全部归到最后一个块中,必定不超过3b个点。

  

 #include <bits/stdc++.h>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=; vector<int> vect[N];
int n, m; void add_edge(int from,int to)
{
vect[from].push_back(to);
vect[to].push_back(from);
} stack<int> stac;
int belongto[N], vis[N], block, pro[N];
void DFS(int x) //num表示后面还剩下几个。
{
vis[x]=;
int cur=stac.size();//x上面的都不要碰。x只能碰它的子树。
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!vis[t])
{
DFS(t);
if(stac.size()-cur >= m) //够m个就组。
{
//把这m个弄出来
pro[++block]=x;//以x作为省会
while(stac.size()>cur)
{
int p=stac.top();
stac.pop();
belongto[p]=block; }
}
}
}
stac.push(x);
} int main()
{
freopen("input.txt", "r", stdin);
int a, b;
while(cin>>n>>m)
{
block=;
memset(vis, , sizeof(vis));
for(int i=; i<=n; i++) vect[i].clear();
for(int i=; i<n; i++)
{
scanf("%d%d",&a,&b);
add_edge(a, b);
} DFS();//从任意点遍历
while(!stac.empty()) //可能有余下的点
{
int p=stac.top();
stac.pop();
belongto[p]=block;
}
if(n<m) printf("0\n");//不够1块
else
{
printf("%d\n",block);
for(int i=; i<=n; i++) printf("%d ", belongto[i]);
printf("\n");
for(int i=; i<=block; i++) printf("%d ", pro[i]);
printf("\n");
}
} return ;
}

AC代码

HYSBZ 1086 王室联邦 (树的分块)的更多相关文章

  1. BZOJ 1086 王室联邦 | BFS

    BZOJ 1086 王室联邦 题意 把一棵树分块,每块大小在[B, 3B]之间(B由输入数据给出),每个块需要对应一个核心点,核心点可以在块内,这个点要满足块内每个点到核心点的路径上的点都属于这个块( ...

  2. BZOJ1086 王室联邦 —— 树分块

    题目链接:https://vjudge.net/problem/HYSBZ-1086 1086: [SCOI2005]王室联邦 Time Limit: 10 Sec  Memory Limit: 16 ...

  3. bzoj1086 [SCOI2005]王室联邦 树分块

    [bzoj1086][SCOI2005]王室联邦 2014年11月14日2,6590 Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的 ...

  4. BZOJ1086: [SCOI2005]王室联邦(贪心,分块?)

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 2610  Solved: 1584[Submit][Status] ...

  5. 【bzoj1086】[SCOI2005]王室联邦 树分块

    题目描述 将一棵n个点的树分为若干“块”,每个块满足:大小在B到3B之间,并且这个“块”添加某个点后连通.求方案. 输入 第一行包含两个数N,B(1<=N<=1000, 1 <= B ...

  6. BZOJ 1086 王室联邦

    http://www.lydsy.com/JudgeOnline/problem.php?id=1086 思路:贪心,每次当储存的儿子大于等于B时,分出一个块,这样每次每个块至多为2B,这样剩下的没有 ...

  7. 【P2325】王室联邦(树的遍历+贪心)

    在肖明 #神#的推荐下,我尝试了这个题,一开始想的是暴力枚举所有的点,然后bfs层数,试着和肖明 #神#说了这种方法之后, #神#轻蔑的一笑,说这不就是一个贪心么,你只需要先建树,然后从底下向上遍历, ...

  8. bzoj 1086 王室联邦 —— 思路题

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1086 一眼看去很是不会,于是看看TJ... https://blog.csdn.net/ly ...

  9. BZOJ 1086 & 类树的分块

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

随机推荐

  1. Intel® Media SDK(一)

    A cross-platform API for developing media applications on Windows* Fast video playback, encode, proc ...

  2. boost之timer

    1. timer类实现 #pragma once #include <ctime> #include <limits> class timer { public: timer( ...

  3. HNOI2008 GT考试 (KMP + 矩阵乘法)

    传送门 这道题目的题意描述,通俗一点说就是这样:有一个长度为n的数字串(其中每一位都可以是0到9之间任意一个数字),给定一个长度为m的模式串,求有多少种情况,使得此模式串不为数字串的任意一个子串.结果 ...

  4. bzoj2878 [Noi2012]迷失游乐园——概率期望DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2878 这个博客写得很好:https://www.cnblogs.com/qt666/p/72 ...

  5. 深入理解js里面的this

    闲聊两句(可以忽略): 毕业有半年了,时间还过得真快,不过还好,感觉自己相对于刚毕业那会确实成长了很多:好久没有打游戏了(自己决心要戒掉的),消磨时光的时候就看看电影或者追追电视剧,再无聊就洗洗衣服. ...

  6. (水题)洛谷 - P1598 - 垂直柱状图

    https://www.luogu.org/problemnew/show/P1598 忘记读取后清空数组,也不知道准确的长度. #include<bits/stdc++.h> using ...

  7. c++常见面试题30道

    1.new.delete.malloc.free关系 delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数.malloc与free是C++/C语言的标准库函数,new ...

  8. poj2186【利用强连通分量】

    题意: 有n头奶牛,然后有个规则是A->B,B->C,那么A->C: A觉得B受欢迎,B觉得C受欢迎,那么A觉得C受欢迎: 求:被其他所有牛都欢迎的牛的数量: 思路: 原来的思路: ...

  9. Apereo CAS Server服务端搭建教程

    不说废话了,直接看搭建过程吧. 首先到下载源码,https://github.com/apereo/cas-overlay-template/tree/4.2 附上地址,本次版本为4.2,下载源码后如 ...

  10. 第九篇 .NET高级技术ref、out

    普通参数是“值类型传递拷贝,引用类型传递引用”,但是都不能在函数内部修改外部变量的指向(p.Age=5不是可以吗?),这时候要用ref或者out(相当于把变量都传进去了),他们的作用不同:ref的作用 ...