FZU2185 树的路径覆盖

贪心的搜索也能做:http://blog.csdn.net/u013611908/article/details/44572549

转自:http://vainman.coding.io/


http://acm.fzu.edu.cn/problem.php?pid=2185

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

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

Sample Input
2

1

7

0 0 1 1 2 2
Sample Output
0 0

2 3

(预警:下面未必是对的,求指正)

先看第一问,一开始就猜可能是叶子数的一半,当时没证出来,看见别的题比较多人过就弃了这题。。。晚上才慢慢想到,,,,

首先,不可能用少于(L+1)/2条路径来覆盖所有的边,否则必然有不少于一个叶子的邻边没有被覆盖。

然后是(L+1)/2条边一定可以覆盖所有的边,可以用个类似于树的重心的特殊点来简略证明,这个点(设为C)是:

设整棵树的有L个叶子,这个点C满足以它的邻点为根的子树的叶子数都不超过L/2,那么每次只要从叶子最少的子树向最多叶子的子树连路径覆盖即可,这样,这些叶子之间的路径都经过这个特殊点C,对于任意一条边,都会被延伸向这条边下面的叶子结点的路径覆盖。

对于任意一棵树,一定可以找到这样的一个点:从任意一个点出发,设当前的点为v,最多只有一个子树的叶子数大于L/2(总共才L个叶子嘛。。),如果有这样一个子树T,那么把它的根置为v,重复下去,直到不存在叶子数大于L/2的子树,这时的当前点v就是我们要找的点了。

再看第二问,考虑叶子Vx的父亲结点F,显然最多有一个叶子能通过它的父亲F延伸出去,所以当F的子结点多于1个时,必然是两个两个地连路径覆盖,同时删除它们,剩下的就是一个子问题(如果F有奇数个子结点,最后剩下的点Vx到F到F的父亲是条链,压缩即可)。这样,对于一个点,它对答案的贡献是(它的度数 – 1)/2,但是到最后根结点是没有父亲的,这时算漏了一条边,最后要加上去(当然如果只有一个点是不用加的)。DFS一遍也是可以的,一开始就是这样子想的,后来一个邻校的朋友问用点的度数可不可以才发现这挺(jian)萌(dan)的好方法。。。

 

所以,答案就是(叶子个数+1)/2 和 sigma{ (度数-1)/2 } + (点数>1)

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define rep1(i, n) for(int i = 1; i <= (n); ++i)
const int N = 100010;
int a[N], n;
int main(){
    int _, x;
    scanf("%d", &_);
    while(_--){
        scanf("%d", &n);
        memset(a, 0, sizeof(a[0]) * n);
        rep(i, n - 1) scanf("%d", &x), ++a[i + 1], ++a[x];
        int a1 = 0, a2 = 0;
        rep(i, n) a1 += (a[i] == 1), a2 += (a[i] - 1) / 2;
        printf("%d %d\n", (a1 + 1) / 2, a2 + (n > 1));
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值