【FZU 2185】 Problem 2185 树的路径覆盖(建树)

【FZU 2185】 Problem 2185 树的路径覆盖(建树)

 Problem 2185 树的路径覆盖

Accept: 100    Submit: 275
Time Limit: 2000 mSec    Memory Limit : 32768 KB

 Problem Description

給一棵树, 用最少的路径去覆盖所有的边, 求(1)允许边被重复覆盖, (2)不允许边被重复覆盖.

 Input

第一行是组数T(T <= 20). 每组两行, 第一行是n(1 <= n <= 10^5), 第二行是n - 1个数(0-based), 第i个数x[i]表示有一条边(x[i], i + 1), (0 <= i <= n - 2).

 Output

两个值,第一个值是允许边被重复覆盖情况下的答案,第二个值是不允许边被重复覆盖下的答案,用一个空格分隔.

 Sample Input

2170 0 1 1 2 2

 Sample Output

0 02 3

 Source

FOJ有奖月赛-2015年03月

给出一颗0为根的树(不一定为二叉树) 结点编号0~n-1 问可重复最少覆盖路径数和不可重复最少覆盖路径数

可重复好想 两个两个叶子结点间连路 为(leaf+1)/2叶子结点的一半(向上取整)

不可重复的 先把枝叶去掉 只留下一整棵树 答案同为叶子结点一半

当某个节点有分支时 其实是问以该节点为根的新树上不可重复最少覆盖路径数 同上处理

去分支 后的叶子结点 其实就是根的出度

这样统计各结点的出度的一半 由于从非0结点发出的边有一条包含于0(总父亲)内 因此需要向下取整 统计之后即为答案


代码如下:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>

using namespace std;

int out[100010];

int main()
{
    int t,n,u,leaf,ans;
    scanf("%d",&t);
    while(t--)
    {
        memset(out,0,sizeof(out));
        scanf("%d",&n);
        for(int i = 1; i < n; ++i)
        {
            scanf("%d",&u);
            out[u]++;
        }

        leaf = 0;
        ans = (out[0]+1)>>1;
        for(int i = 1; i < n; ++i)
        {
            if(!out[i]) leaf++;
            ans += out[i]>>1;
        }
        printf("%d %d\n",(leaf+1)>>1,ans);
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值