在 图 上 多 画 一 画 , 想 一 想 \color{Red}在图上多画一画,想一想 在图上多画一画,想一想
贪 心 策 略 : 以 1 为 中 心 , 引 出 k 条 路 径 \color{orange}贪心策略:以1为中心,引出k条路径 贪心策略:以1为中心,引出k条路径
然 后 用 n − k − 1 个 点 均 匀 添 加 到 这 k 条 路 径 上 然后用n-k-1个点均匀添加到这k条路径上 然后用n−k−1个点均匀添加到这k条路径上
最 后 把 k 个 叶 子 节 点 均 匀 的 添 加 到 最 外 层 的 k 条 路 径 上 最后把k个叶子节点均匀的添加到最外层的k条路径上 最后把k个叶子节点均匀的添加到最外层的k条路径上
why??????????????????????
你 看 呐 , 不 管 怎 么 连 边 , 这 个 图 都 一 定 有 k 个 叶 子 节 点 在 最 外 面 你看呐,不管怎么连边,这个图都一定有k个叶子节点在最外面 你看呐,不管怎么连边,这个图都一定有k个叶子节点在最外面
假 如 一 旦 分 配 的 不 均 匀 了 , 那 一 定 有 的 路 径 长 , 有 的 路 径 短 假如一旦分配的不均匀了,那一定有的路径长,有的路径短 假如一旦分配的不均匀了,那一定有的路径长,有的路径短
这 么 一 来 , 最 远 的 两 个 叶 子 节 点 的 路 径 就 会 很 长 , 那 我 们 肯 定 均 匀 分 配 呀 ! 这么一来,最远的两个叶子节点的路径就会很长,那我们肯定均匀分配呀! 这么一来,最远的两个叶子节点的路径就会很长,那我们肯定均匀分配呀!
至于实现方法,因人而异
但 是 多 想 一 下 , 就 能 少 些 一 点 。 别 像 我 一 样 , 写 的 很 复 杂 但是多想一下,就能少些一点。别像我一样,写的很复杂 但是多想一下,就能少些一点。别像我一样,写的很复杂
大牛的简短代码
#include
using namespace std;
int n,k;
int main()
{
cin >> n >> k;
n--;//除掉1中心的这个点
int ans=n/k*2;//最长的两条边
if( n%k==1 ) ans++;//有一条边突出
else if( n%k>1 ) ans+=2;//多余一条边突出
cout<
me的复杂程序
#include
using namespace std;
const int maxn=2e5+10;
int n,k,top;
int a[maxn],num[maxn];//a数组表示第i条路径最外层的点,num数组表示第i条路径有几条边
typedef pairp;
p s[maxn];
int main()
{
cin>>n>>k;
int x=n-k;//非叶子节点
x--;//1已经用掉了
for(int i=1;i<=k;i++) a[i]=1;
int now=2;
while(x)//
{
for(int i=1;i<=k;i++)
{
if(x)
{
s[++top]=p(now,a[i]);
x--,a[i]=now++,num[i]++;
}
else break;
}
}
//现在开始构造k个叶子节点
for(int i=n-k+1,j=1;i<=n;i++,j++) s[++top]=p(i,a[j]),num[j]++;
int er=0,ci=0;
for(int i=1;i<=k;i++)
{
if(num[i]>=ci) er=ci,ci=num[i];//找最长的两条路径
else if(num[i]>er) er=num[i];
}
cout<