Problem
要求构造 n 个点树,使得叶子节点仅有 k 个,同时树的直径尽可能短。输出最短树的直径,及构造方案。
限制条件
3≤n≤2⋅105
2≤k≤n−1
解法
特判非叶子节点数为 1, 2 的情况。
以任意一点为根 R,叶子节点数为 k ,即表示根 R 可以连接 k 条链。使得树直径最小即使得每条链的长度平均。此时的最长链长+最短链长为树的直径。
代码
#include<bits/stdc++.h>
using namespace std;
int fa[200010];
int main()
{
int n, k, o;
scanf("%d %d", &n, &k);
o = n-k;
if(o == 1) {
printf("2\n");
for(int i=2;i<=n;i++) printf("1 %d\n", i);
} else if(o == 2) {
printf("3\n2 3\n1 2\n");
for(int i=4;i<=n;i++) printf("1 %d\n", i);
} else {
o--;
int level = o/k*2+2;
if(o%k >= 2) level += 2;
else if(o%k==1) level++;
printf("%d\n", level);
for(int i=2;i<=n;i++)
printf("%d %d\n", max(i-k, 1), i);
}
}