Strategic Game(树形DP)

目录

  • Strategic Game(树形DP)

    • 题目
    • 题意
    • 思路
    • 题解

Strategic Game(树形DP)

题目

Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which form a tree. He has to put the minimum number of soldiers on the nodes so that they can observe all the edges. Can you help him?

Your program should find the minimum number of soldiers that Bob has to put for a given tree.

The input file contains several data sets in text format. Each data set represents a tree with the following description:

the number of nodes
the description of each node in the following format

node_identifier:(number_of_roads) node_identifier1 node_identifier2 ... node_identifier
or
node_identifier:(0) 

The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500). Every edge appears only once in the input data.

For example for the tree:

the solution is one soldier ( at the node 1).

The output should be printed on the standard output. For each given input data set, print one integer number in a single line that gives the result (the minimum number of soldiers). An example is given in the following table:
Input
4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)
Output
1
2
Sample Input
4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)
Sample Output
1
2

题意

给定一棵树,树的每一个边至少要有一个点,求最少要多少点。

思路

简单的树形dp

  • 因为要从自己点推父节点,所以可以使用递归。
  • 父节点不放的话,子节点必须放。父节点放的话子节点可放可不放。
    故得到:
    dp[u][0] += dp[v][1];
    dp[u][1] += min(dp[v][0], dp[v][1]);

题解

//简单的树形dp
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define N 1805
using namespace std;

vector<int> eg[N];
int dp[N][N];
int parent[N];
int n;

int dfs(int u)
{
   dp[u][0] = 0;
   dp[u][1] = 1;//自己放的话先加上自己的,子节点的在下面遍历他们的时候会加上。

   for (int i = 0; i < eg[u].size(); i++)
   {
      int v = eg[u][i];
      dfs(v);
      dp[u][0] += dp[v][1];
      dp[u][1] += min(dp[v][0], dp[v][1]);
   }
}

int main()
{

   while (scanf("%d", &n) != EOF)
   {
      memset(parent, -1, sizeof parent);
      memset(dp, 0, sizeof dp);
      int x, k, y;
      for (int i = 0; i < n; i++)
      {
         scanf("%d:(%d)", &x, &k);
         for (int j = 0; j < k; j++)
         {
            scanf("%d", &y);
            parent[y] = x;
            eg[x].push_back(y);
         }
      }

      int root = 0;
      while (parent[root] != -1)
      {
         root = parent[root];
      }
      dfs(root);
      cout << min(dp[root][0], dp[root][1]) << endl;
      for (int i = 0; i < n; i++)
         eg[i].clear();
      //
   }
}

原文地址:https://www.cnblogs.com/tttfu/p/11293746.html

时间: 2024-10-14 07:07:34

Strategic Game(树形DP)的相关文章

POJ 1463 Strategic game( 树形DP )

题意:一颗 N 个节点的树,在某一个节点上放置一个兵则可以守住与它相邻的边.最少放置多少个兵才可以守住所有的边. #include <cstdio> #include <deque> using namespace std; #define ABANDON 0 #define GET 1 deque< int > graph[2010]; int DP[2010][2]; void DFS( int start, int parent ){ DP[start][ABAN

HDU 1054 Strategic Game (树形dp)

题目链接 题意: 给一颗树,用最少的点覆盖整棵树. 分析: 1:以当前节点为根节点,在该节点排士兵守护道路的最小消耗.在这种情况下,他的子节点可以安排士兵,也可以不安排士兵.可以从各个子节点两个不同状态(存在士兵,不存在士兵)的最值中选出最小的消耗,然后相加就求出了当前节点派士兵的最小消耗. 2:以当前节点为根节点,不存在士兵.这种情况十分清楚,因为当前节点没有士兵,那么这个节点到子节点之间的道路没有人守护,那么子节点就必须要安排士兵,因此这种情况下.这个节点的最小消耗就是每个子节点存在士兵的情

HDU 1054 Strategic Game(树形DP)

Problem Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of which for

Strategic game(POJ 1463 树形DP)

Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 7490   Accepted: 3483 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad

UVa 2038 - Strategic game(二分图最小顶点覆盖 or 树形DP)

Strategic game Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend a medieval city, the roads of wh

POJ 1463 Strategic game 最小点覆盖集(树形dp)

点击打开链接 Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 6105   Accepted: 2808 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is v

树形dp compare E - Cell Phone Network POJ - 3659 B - Strategic game POJ - 1463

B - Strategic game POJ - 1463 题目大意:给你一棵树,让你放最少的东西来覆盖所有的边 这个题目之前写过,就是一个简单的树形dp的板题,因为这个每一个节点都需要挺好处理的. 这个树形dp是从底往根部来递推,所以每一个点,都是由它的根节点来递推的. 如果一个根节点的子节点放了东西,那么这个根节点就可以有选择,但是如果没有放东西,那么这个根节点就必须放东西. E - Cell Phone Network POJ - 3659 题目大意:给你一棵树,让你用最小的东西来覆盖所有

hdu1054 Strategic Game(最小覆盖点-树形dp)

题目链接:点击打开链接 题意描述:给一棵树,找最少的点集能把树上的所有边覆盖掉? 解题思路:典型的最小覆盖点 树形dp即可 dp[i][0]:表示如果不选i点则dp[i][0]+=dp[t][1];///表示要选所有的儿子节点 dp[i][1]:表示如果选i点则dp[i][1]+=min(dp[t][0],dp[t][1]);///表示选择其儿子节点中较小的情况 代码: #pragma comment(linker,"/STACK:1024000000,1024000000") #in

HDU ACM 1054 Strategic Game 二分图最小顶点覆盖?树形DP

分析:这里使用树形DP做. 1.最小顶点覆盖做法:最小顶点覆盖 == 最大匹配(双向图)/2. 2.树形DP: dp[i][0]表示i为根节点,并且该节点不放,所需的最少的点数. dp[i][1]表示i为根节点,并且该节点放,所需要的最少的点数. dp[i][0]=sum(dp[son[i][j]][1]) 该点不放,则它的儿子节点必须都放,只有这样之间的边才可以被覆盖. dp[i][1]=sum(min(dp[son[i][j]][0],dp[son[i][j]][1])) 该点放的话,则它的