CodeForces Round#423 Div2D&Div1B(827B) Solution

题意:要求输出一棵树的形态(即树的边),要求:总共有n个点,其中k个叶子节点(度为1),并且这棵树的直径要最小。

题解:考虑一棵树,先画出一条直径,现在假设这个直径是最小的,那么现在考虑如何向直径链上加入树的所有节点,且不使得树的直径变大,学过均值的同学都知道要找到直径的中点,然后向外延伸一条链(树枝),否则,如果更偏左边一些,那么直径的右链和新加入的链的直径会超过原有直径。而我们又想让一条链可以消耗尽可能少的叶子数量,并且带有尽可能多的节点,那么显然就是没有枝杈的赤裸裸的链最节省叶子节点数。那么现在这棵树的形态一定是:一个根节点,向外辐射出若干条赤裸的链。再来考虑致敬最小这个条件,我们希望每条链平摊最少的节点,那么就平均分就可以了,最后多的几个就分到不同的链上一条链一个就好了。说了半天…………其实就是找一个根节点,然后向外长k个链,转着圈加节点就行了。。

Code:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
int length[MAXN];
int n,k;
int main(){
    cin>>n>>k;
    n--;
    int delta = n%k;
    int length = n/k;
    int now =1;
    if (delta>=2){
        cout<<2*(length+1)<<endl;
    }else if (delta==1){
        cout<<2*length+1<<endl;
    }else{
        cout<<2*length<<endl;
    }
    for (int i=0;i<delta;i++){
        now++;
        cout<<"1 "<<now<<endl;
        for (int j=1;j<length+1;j++){
            now++;
            cout<<now<<" "<<now-1<<endl;
        }
    }
    for (int i=0;i<k-delta;i++){
        now++;
        cout<<"1 "<<now<<endl;
        for (int j=1;j<length;j++){
            now++;
            cout<<now<<" "<<now-1<<endl;
        }
    }
    return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值