[bzoj1086]王室联邦
2016-05-09 18:52
253 查看
题目描述
“余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理。他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个不同的城市之间有且仅有一条
直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个
城市。每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经
过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。一个城市可以作为多个省的省会。聪明的
你快帮帮这个国王吧!
greedy
由于我太弱了就去orz了hzwer的题解无解情况是n<b。
接下来我们来弄一个贪心。
贪心方法见代码。
#include<cstdio> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; const int maxn=1000+10; int h[maxn],go[maxn*2],next[maxn*2],size[maxn],belong[maxn],cap[maxn],s[maxn]; int i,j,k,l,t,n,m,c,tot,top,cnt; void add(int x,int y){ go[++tot]=y; next[tot]=h[x]; h[x]=tot; } void dfs(int x,int y){ s[++top]=x; int t=h[x]; while (t){ if (go[t]!=y){ dfs(go[t],x); size[x]+=size[go[t]]; if (size[x]>=c){ size[x]=0; cap[++cnt]=x; while (s[top]!=x) belong[s[top--]]=cnt; } } t=next[t]; } size[x]++; } void dg(int x,int y,int z){ if (belong[x]) z=belong[x];else belong[x]=z; int t=h[x]; while (t){ if (go[t]!=y) dg(go[t],x,z); t=next[t]; } } int main(){ scanf("%d%d",&n,&c); if (n<c){ printf("0\n"); return 0; } fo(i,1,n-1){ scanf("%d%d",&j,&k); add(j,k);add(k,j); } dfs(1,0); if (!cnt) cap[cnt=1]=1; dg(1,0,cnt); printf("%d\n",cnt); fo(i,1,n) printf("%d%c",belong[i],(i==n)?'\n':' '); fo(i,1,cnt) printf("%d%c",cap[i],(i==cnt)?'\n':' '); }
相关文章推荐
- C++ Primer 学习笔记_73_面向对象编程 -再谈文本查询示范
- DELPHI美化界面
- 反射概念:获取class文件对象的三种方式
- 团体程序设计天梯赛-练习集 L2-1. 紧急救援 Dijstra单源最短路径拓展应用
- 《精益创业》读后思考 2
- boost编译随笔
- C++ Primer 学习笔记_72_面向对象编程 -句柄类与继承[续]
- C++ Primer 学习笔记_71_面向对象编程 --句柄类与继承
- 菜刀ASP 删除文件抓包
- 数据库三大范式详解
- efwplus框架
- 本地音乐播放器(三)
- 自己上传jar包到我们的maven本地仓库中
- C++ Primer 学习笔记_70_面向对象编程 -纯虚函数、器皿与继承
- Java NIO使用及原理之--缓冲器buffer(1)
- SSH攻击
- Android KeyStore + FingerprintManager 存储密码
- C++ Primer 学习笔记_69_面向对象编程 -继承景况下的类作用域
- 链表——循环右移链表的后K个结点
- C++ Primer 学习笔记_68_面向对象编程 -构造函数跟复制控制[续]