# BZOJ1086 [SCOI2005]王室联邦 【dfs + 贪心】

## 题目

“余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省，每个省都由他们王室联邦的一个成

## 输入格式

第一行包含两个数N，B（1<=N<=1000, 1 <= B <= N）。接下来N－1行，每行描述一条边，包含两个数，即这

## 输出格式

如果无法满足国王的要求，输出0。否则输出数K，表示你给出的划分方案中省的个数，编号为1..K。第二行输

8 2

1 2

2 3

1 8

8 7

8 6

4 6

6 5

3

2 1 1 3 3 3 3 2

2 1 8

## 题解

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u]; k != -1; k = ed[k].nxt)
using namespace std;
const int maxn = 1005,maxm = 2005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int N,B,h[maxn],ne = 0;
struct EDGE{int to,nxt;}ed[maxm];
inline void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v]}; h[v] = ne++;
}
int st[maxn],fa[maxn],top = 0,cnt = 0,id[maxn],cap[maxn];
void dfs(int u){
int to,last = top;
Redge(u) if ((to = ed[k].to) != fa[u]){
fa[to] = u;
dfs(to);
if (top - last >= B){
cap[++cnt] = u;
while (top > last) id[st[top--]] = cnt;
}
}
st[++top] = u;
}
int main(){
memset(h,-1,sizeof(h));
N = RD(); B = RD();
REP(i,N - 1) build(RD(),RD());
dfs(1);
while (top) id[st[top--]] = cnt;
printf("%d\n%d",cnt,id[1]);
for (int i = 2; i <= N; i++) printf(" %d",id[i]); printf("\n%d",cap[1]);
for (int i = 2; i <= cnt; i++) printf(" %d",cap[i]);
return 0;;
}

posted @ 2018-01-03 17:57  Mychael  阅读(104)  评论(0编辑  收藏  举报