2020牛客多校赛第二场 C题 Cover the Tree

本文探讨了在无根树中寻找最少链数以覆盖所有节点的问题,通过分析树的特性,提出了一种基于叶节点数量的算法。该算法不仅能够确定最少链数,还能输出这些链的具体构成,为理解树的遍历和覆盖提供了新的视角。

在这里插入图片描述
题意:
这题大意是构建一个无根的树,让你求最少几条链能把树的结点都包含在内,并且输出链(答案不唯一,输出即可)
所以输入是构建一个树。
分析+思路:
这题签到题一看到树就知道是找规律+dfs,你多画几种情况,看看结果与n的关系就可以玄学证明得出:
记叶节点为p1,p2,pn,共ans个。
最少链数=(ans+1)/2(整除);
并且输出链能完美包含的情况就是pi和pi+ans/2;(也就是如果偶数就分半,分半对应,奇数就第一个数对应最中间的那个数,最中间那个树对应最后一个树,(本来最原始的理解是分半,一一对应,出现有中间让他和任意一个对应即可))
这里本来打算老老实实模拟dfs树,但是后来突然发现,只用记录哪个是叶节点就好了,直接定义一个数组,只出现了一次的元素就是叶节点,另外定义一个数组记录下来,ans自然就也出来了,主要还是这个玄学证明。
ac代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int ans,a[N],u,v,p[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&u,&v);
        a[u]++,a[v]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i]==1)
        {
            p[++ans]=i;
        }
    }
    printf("%d\n",(ans+1)/2);
    for(int i=1;i<=(ans+1)/2;i++)
    printf("%d %d\n",p[i],p[i+ans/2]);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值