Tree DP | 1: - Example: games

Games

Achievement 10 opening time 2020 March 10 Tuesday, 07:55
discount 0.8 Discount Time 2020 Tuesday, April 7 23:55
Allow late no Closing time 2020 Tuesday, April 7 23:55

Someone likes to play computer games, especially strategic game, but sometimes he can not find a solution as soon as possible so I often feel very depressed. Now faced with the following question: he must be in a fortified medieval castle, the castle road forming an undirected tree. To schedule a minimum of soldiers at the junction so that they can see all sides. Can you help him?

Your task is given a minimum number of soldiers.

Comprising a plurality of sets of input data. Each set of data represents a tree, in each set of data:

The first row is the number of nodes.

The next few lines of a node is described in the following format:

Node Identifier: (number of roads) the node identifier of a node identifier of the node identifier number 2 ...... Road

or

Node Identifier: (0)

For n (0 <n <= 1500) nodes, the node identifier is a number from 0 to n - 1 is an integer. Each edge appears only once in the test case.

For each set of data, each represented by an integer given minimum number of soldiers.

  Test input Expected output time limit Memory Limit Additional process
Test Case 1  
  1. 4↵
  2. 0:(1) 1↵
  3. 1:(2) 2 3↵
  4. 2:(0)↵
  5. 3:(0)↵
  6. 5↵
  7. 3:(3) 1 4 2↵
  8. 1:(1) 0↵
  9. 2:(0)↵
  10. 0:(0)↵
  11. 4:(0)↵
 
  1. 1↵
  2. 2↵
1 second 64M 0

This gives the tree problem, several nodes in the upper part of soldiers required, so that they can see all sides.

1, the input of the processing - FIG stored

The title of the tree, which is a connected undirected acyclic graph. Consider  adjacency lists  to store. (Vector container will be used to simplify operation of the list)

Topic showed that: each side will only be entered once. That is, for ab side when you enter, if entered after a point b, then the points will not be entered after a b a. The title of this map is an undirected graph, for the convenience of our generalized graph traversal, should when dealing with input and construct graph, edge up between the two points you want the whole: that is, for the edge ab, we can b to access a, b may be accessed through a.

2, finding the optimal dynamic deployment - Deep Search

To ensure that each side needs to be seen, then the two ends of each side must have at least one end of the soldiers . Each point you have two options: put the soldiers, hold soldiers . The structure and characteristics of the tree: the sub-node under the root node a number of root, node and each byte and its descendants can be seen as a subtree. So we can use deep search: search root root, followed by continuing the search for each of the sub-tree root . (First root could choose)

Using a two-dimensional array dp [0..n-1, 0..1] to record the minimum number:

  • When the minimum number of root node hold soldiers to root for the root of the tree needed: dp [root] [0]
  • When the minimum number of soldiers put root node, the root is the root of the tree needed: dp [root] [1]

This question should be a bottom-up solution:

First the sub-tree (set its node next) the dp [next] [0], dp [next] [1] is calculated, to be calculated on the basis of one of the sub-tree tree (set its node root) the dp [root] [0], dp [root] [1]. The final answer should be dp [root] [0], dp [root] small value [1].

Construction of the equation of state: 

So how to migrate from a fruit tree to tree the whole of it? In two ways:

  • If the root node hold soldiers: that each child soldiers must be placed next node, you must select dp [next] [1]
  • If the root node discharge soldiers: each of its child nodes can be placed next soldier soldiers may hold, should be selected dp [next] [0] and DP [next] small value [1], together with the root itself One

Therefore, the state transition equation is as follows:

dp[root][0] = \sum dp[next][1]

\bg_white dp[root][1] =1 + \sum min(dp[next][0], dp[next][1])


AC Complete Code:

//
// Created by LittleCat on 2020/3/10.
//

#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>

using namespace std;
#define MAX 1550

vector<int> point[MAX]; //map[i]储存节点i的临接节点集
bool vis[MAX];  //vis[i]表示节点i是否被访问过
int dp[MAX][2];

void DFS(int root) {
    vis[root] = true;   //标记已访问节点
    /* 依次遍历根节点的每一个子节点 */
    for (int i = 0; i < point[root].size(); i++) {
        int next = point[root][i];   //子节点
        if (vis[next])   //是已访问的前驱节点
            continue;  //避免往回搜索
        DFS(next);  //搜索子节点
        dp[root][0] += dp[next][1];
        dp[root][1] += min(dp[next][0], dp[next][1]);
    }
    dp[root][1]++;
}

int main() {
    int n;
    while (EOF != scanf("%d", &n)) {
        /* 初始化数组 */
        for (auto & i : point)
            i.clear();
        memset(vis, false, sizeof(vis));
        memset(dp, 0, sizeof(dp));
        /* 处理输入 */
        for (int i, k; n; n--) {
            scanf("%d:(%d)", &i, &k);  //前驱节点i,边数k
            for (int j; k; k--) {
                scanf("%d", &j);  //后继节点j
                point[i].push_back(j);
                point[j].push_back(i);
            }
        }
        int root = 0;
        DFS(root);
        printf("%d\n", min(dp[root][0], dp[root][1]));
    }
}

 


Have any questions please review the exchange, if you wish this article helpful little bit of praise, hee hee ~  



No personal welcome attention to the public "programming chicken wings", here is a serious and well-behaved code agricultural one.

---- do the most well-behaved blog er, do the most solid programmer ----

Aims to carefully write each article, usually aggregated into notes will push updates -

Here Insert Picture Description

Published 138 original articles · won praise 63 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_43787043/article/details/104970405