HYSBZ 1086 王室联邦 (树的分块)
题意:国王想把他的国家划分成若干个省。他的国家有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 王室联邦 (树的分块)的更多相关文章
- BZOJ 1086 王室联邦 | BFS
BZOJ 1086 王室联邦 题意 把一棵树分块,每块大小在[B, 3B]之间(B由输入数据给出),每个块需要对应一个核心点,核心点可以在块内,这个点要满足块内每个点到核心点的路径上的点都属于这个块( ...
- BZOJ1086 王室联邦 —— 树分块
题目链接:https://vjudge.net/problem/HYSBZ-1086 1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 16 ...
- bzoj1086 [SCOI2005]王室联邦 树分块
[bzoj1086][SCOI2005]王室联邦 2014年11月14日2,6590 Description “余”人国的国王想重新编制他的国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的 ...
- BZOJ1086: [SCOI2005]王室联邦(贪心,分块?)
Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 2610 Solved: 1584[Submit][Status] ...
- 【bzoj1086】[SCOI2005]王室联邦 树分块
题目描述 将一棵n个点的树分为若干“块”,每个块满足:大小在B到3B之间,并且这个“块”添加某个点后连通.求方案. 输入 第一行包含两个数N,B(1<=N<=1000, 1 <= B ...
- BZOJ 1086 王室联邦
http://www.lydsy.com/JudgeOnline/problem.php?id=1086 思路:贪心,每次当储存的儿子大于等于B时,分出一个块,这样每次每个块至多为2B,这样剩下的没有 ...
- 【P2325】王室联邦(树的遍历+贪心)
在肖明 #神#的推荐下,我尝试了这个题,一开始想的是暴力枚举所有的点,然后bfs层数,试着和肖明 #神#说了这种方法之后, #神#轻蔑的一笑,说这不就是一个贪心么,你只需要先建树,然后从底下向上遍历, ...
- bzoj 1086 王室联邦 —— 思路题
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1086 一眼看去很是不会,于是看看TJ... https://blog.csdn.net/ly ...
- BZOJ 1086 & 类树的分块
题意: “余”人国的国王想重新编制他的 国家.他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理.他的国家有n个城市,编号为1..n.一些城市之间有道路相连,任意两个 不同的城市之间 ...
随机推荐
- bzoj3270博物馆——期望概率DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3270 设计一个状态表示两个人分别在两个点的状态,带个标号num[i][j]: 据此得到状态之 ...
- 微信小程序在线制作 自己制作微信小程序
小程序是个什么东西?怎么自己制作微信小程序?微信小程序在线制作难吗?最近老是听这类问题,耳朵都长茧子了. 百牛信息技术bainiu.ltd整理发布于博客园 接下来作为一个技术人员的角度就为大家分析一下 ...
- UI:多线程 、用GCD创建线程
什么是应用(程序):就是我们编写的代码编译后生成的app文件 进程:凡是一个运行的程序都可以看作为一个进程,如打开的多个 word,就可以认为是一个进程的多个线程. 线程:至少有一个线程就是主线程,网 ...
- linux中用无名管道进行文件的读写
1管道是什么: 水管子大家知道,有两端,在此一端用来读一端用来写,其中一端的输出作为另外一端的输入. 2 函数原型 int pipe(int pipefd[2]);//参数中分别代表的两端 3 例子: ...
- Win32控制台程序和Win32应用程序
刚接触Windows那一套,大多数概念都还没建立起来,整理了一下网上对“Win32控制台程序”的理解,谢谢各位网友了. win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境下运 ...
- 数位dp真·浅谈 By cellur925
预警:由于是从$Vergil$学长那里和$Mathison$大神那里学来的,所以清一色记忆化搜索!qwq 巨佬的数位dp讲解(未来的咕咕日报头条): https://www.luogu.org/blo ...
- Codeforces Round #513解题报告(A~E)By cellur925
我是比赛地址 A:Phone Numbers $Description$:给你一串数字,问你能组成多少开头为8的11位电话号码. $Sol$:统计8的数量,与$n$%11作比较. #include&l ...
- scrapy 连接错误
twisted.python.failure.failure twisted.internet.error.connectionlost: connection to the other side w ...
- AtCoder Grand Contest 010 F - Tree Game
题目传送门:https://agc010.contest.atcoder.jp/tasks/agc010_f 题目大意: 给定一棵树,每个节点上有\(a_i\)个石子,某个节点上有一个棋子,两人轮流操 ...
- Oracle apex 搭建
参考文档 : 百度文库 <Oracle ERP APEX开发指南 > APEX HOME: /oracle11g/product/11.2/apex/apex Oracle home: ...