Problem Specification | Value |
---|---|
Time Limit | 10 Sec |
Memory Limit | 162 MB |
Special Judge | Yes |
Submit | 1155 |
Solved | 695 |
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
同树形 DP, 需要 Special Judge.
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stack>
using namespace std;
const int maxn = 2010, maxm = 8010;
int n, B;
class Graph
{
public:
struct edge { int u, v; edge *next; };
edge epool[maxm], *edges[maxn];
int cnt, root, par[maxn], size[maxn];
void addedge(int u, int v)
{
edge *p = &epool[++cnt], *q = &epool[++cnt];
p->u = u; p->v = v; p->next = edges[u]; edges[u] = p;
q->u = v; q->v = u; q->next = edges[v]; edges[v] = q;
return ;
}
// These are the specific operations which would be applied onto the
// province division procedure.
stack<int> cities; // How many cities are pending province division
int city_belong[maxn], // The province ID of the city
capital[maxn], // The capital of the province, in city ID
provinces; // The count of provinces, ID starting from 1
void dfs(int p)
{
size[p] = 0;
cities.push(p);
for (edge *ep = edges[p]; ep; ep = ep->next)
if (ep->v != par[p]) {
par[ep->v] = p;
dfs(ep->v);
size[p] += size[ep->v];
// If the size is sufficient (n > B), we may consume it and not
// count it as a subtree component.
if (size[p] >= B) {
size[p] = 0;
capital[++provinces] = p;
int cit;
// Pop all children of p that were not popped out before,
// these forms the cities of the new province.
while ((cit = cities.top()) != p) { // Take all cities
cities.pop();
city_belong[cit] = provinces; // Set province ID
}
}
}
// You must count oneself!
size[p]++;
return ;
}
// After secure investigation of the function dfs(), we may discover that
// most capitals do not have belongings, where they are not marked available
// as a component. We now format them to belong in at some province.
void format_capitals(int p, int province)
{
if (city_belong[p])
province = city_belong[p];
else
city_belong[p] = province;
// Iterate children
for (edge *ep = edges[p]; ep; ep = ep->next)
if (par[ep->v] == p)
format_capitals(ep->v, province);
return ;
}
} graph;
int main(int argc, char** argv)
{
scanf("%d%d", &n, &B);
// The form is instinctively and factly a tree, according to description.
// The capitol of the provinces are either the root of the subtree or the
// parent of the root of the subtree. This makes division of the tree
// arbitrarily easy. Therefore we may always find a way to satisfy the
// range [B, 3B] easily, given n is sufficient.
if (n < B) {
printf("0\n");
return 0;
}
// Afterwards we read in the data, formally.
for (int i = 1, a, b; i <= n - 1; i++) {
scanf("%d%d", &a, &b);
graph.addedge(a, b);
}
// Deep First Search to generate the tree and calculate subtree size.
graph.dfs(1);
// Reformat capitals to look right
graph.format_capitals(1, graph.provinces);
// Output answer.
printf("%d\n", graph.provinces);
for (int i = 1; i <= n; i++)
printf("%d ", graph.city_belong[i]);
printf("\n");
for (int i = 1; i <= graph.provinces; i++)
printf("%d ", graph.capital[i]);
printf("\n");
return 0;
}