树中走M步最多能访问到几个节点 简单图论 SRM 666 Div1 Easy: WalkOverATree

本文介绍了一种利用有限步数遍历树形结构的算法,通过寻找最大简单路径来最大化访问节点的数量,并在不同情况下优化路径选择策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SRM 666 Div1 EasyWalkOverATree


Problem Statement

Given is a tree on n nodes. The nodes are numbered 0 through n-1. You are given the description of the tree as a int[] parent with n-1 elements. For each valid i, there is an edge between vertices (i+1) and parent[i].

A person is currently standing in node 0. In a single step, the person can move from its current node to any adjacent node. You are given an int L. The person is allowed to make at most L steps.

Return the maximum number of nodes the person can visit during the walk. Node 0 (where the walk starts) and the node where the walk ends count as visited. Each visited node is only counted once, even if it is visited multiple times.

Definition

  • ClassWalkOverATree
  • MethodmaxNodesVisited
  • Parametersvector<int> , int
  • Returnsint
  • Method signatureint maxNodesVisited(vector<int> parent, int L)
(be sure your method is public)

Limits

  • Time limit (s)2.000
  • Memory limit (MB)256

Constraints

  • parent will contain between 0 and 49 elements, inclusive.
  • For each i, parent[i] will be between 0 and i, inclusive.
  • L will be between 1 and 100, inclusive.

Test cases

    • parent{ 0, 0 }
    • L2
    Returns 2
    The tree consists of edges 1-0 and 2-0. Our person will start in node 0 and can make at most  L=2 steps. In two steps, the best we can do is visit one of the nodes 1 and 2.
    • parent{ 0, 0 }
    • L3
    Returns 3
    This is the same tree, only now we have  L=3. In three steps the person can visit all three nodes: for example, by going from node 0 to node 1, back to node 0, and finally to node 2. Note that even though the person visited node 0 twice, we only count it once.
    • parent{ 0, 1, 2, 3 }
    • L2
    Returns 3
    • parent{ 0, 0, 0, 0, 2, 4, 2, 3, 1 }
    • L1
    Returns 2
    • parent{ 0, 0, 1, 2, 3, 2, 3, 1, 3, 0, 1, 8, 6, 8, 0, 5, 15, 0, 9 }
    • L4
    Returns 5
    • parent{ 0, 0, 0, 1, 1, 3, 5, 1, 4, 5, 2, 2, 10, 5, 10, 10, 11, 13, 8, 3, 18, 15, 20, 20, 23, 8, 11, 26, 4 }
    • L26
    Returns 17
    • parent{ 0, 0, 2, 0 }
    • L100
    Returns 5
    As the tree is very small and  L large, the person can easily visit all nodes.
    • parent{ 0, 0, 2 }
    • L4
    Returns 4

题解http://apps.topcoder.com/wiki/display/tc/SRM+666

When maximizing the number of visited nodes using  L  steps, we want to minimize the number of nodes visited more than once. Let's think of the maximal path that doesn't visit any nodes more than once (A simple path). In a tree with maximum depth  d , the maximum simple path starting at node 0 (the root) would contain  d+1  nodes:

So the most nodes we can visit using this strategy is  d+1  nodes, using  L  steps. If  Ld , then we should use this strategy to visit  L+1  nodes - The most we can. This would be optimal because each node costs exactly one step, which is the minimum possible. The issue comes when  d>L , now it might be possible to visit more than the  d+1  nodes in the largest simple path. Imagine we want to visit just one additional node, this will necessarily cost us at least 2 more steps:

It doesn't matter which additional node we pick or what order we try to visit, visiting one more node will costs us two more steps. This is true whenever we want to add any new node to the walk. We can show this by using invariants. As an invariant we have an existing set of nodes that we know we can visit using  x  steps. Then we decide to add one more node to the walk, one whose parent is in the walk. Find the position of the parent node in the walk and insert going to the new node and returning to the walk, increasing the number of steps to  x+2 . After this change, the invariant remains.

Therefore, you start with one node in the walk (the root 0), the first  d  nodes you add to the walk cost one step. Any additional node costs 2 steps. What is the maximum number of nodes you can reach using at most  L  steps? After the first  d  steps we have  Ld  steps left. Every two steps out of the  Ld  steps adds one node:  Ld2  (rounding down). The maximum number of nodes is:  1+d+Ld2 . However, sometimes  L  is so large that this formula can give a result larger than  n  so we just fix this small issue:  min(n,1+d+Ld2) .

The solution consists of finding  d  and then using the formula. Don't forget the corner case when  dL :

int maxNodesVisited(vector<int> parent, int L)
{
    int n = parent.size() + 1;
    // Find d, maximum distance from root to a leaf:
    int d = 0;
    // start with a leaf i and count the number of parents between it and the root:
    for (int i = 1; i < n; i++) {
        int c = 1;
        int x = i;
        while (parent[x-1] != 0) {
            x = parent[x-1];
            c++;
        }
        // remember the maximum c:
        d = std::max(d, c);
    }
    if (d >= L) {
        return L + 1;
    }
    return min(n, 1 + d + (L - d) / 2);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值