Strategic game

Strategic game

https://ac.nowcoder.com/acm/problem/106060

来源:牛客网:

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 10000K,其他语言20000K
64bit IO Format: %lld

题目描述

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.

For example for the tree:
在这里插入图片描述

the solution is one soldier ( at the node 1).
输入描述:
The input 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_identifiernumber_of_roads
or
node_identifier:(0)

The node identifiers are integer numbers between 0 and n-1, for n nodes (0 < n <= 1500);the number_of_roads in each line of input will no more than 10. Every edge appears only once in the input data.
输出描述:
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:
示例1
输入
复制

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)

输出
复制

1
2

题解:

试题:一个树,在一个节点放兵,周围的边就被守护,问最少放多少兵
确定状态:
dp[x][1]以x为根的子树全被看住且在x上放置士兵的最少所需的士兵数量
dp[x][0]以x为根的子树全被看住且在x上没有 放置士兵的最少所需的士兵数量.
确定状态方程:
dp[x][1]=1+∑min(dp[i][0],dp[i][1])//x上放了士兵,x的儿子们可放可不放
dp[x][0]=∑dp[i][1]//如果x不放士兵,x的儿子必须放
结果min(dp[root][0],dp[root][1])
i是x的儿子
相当于我们在考虑x点时,x的子节点都是被考虑完的,x能否被覆盖完全取决于自身或x的儿子

代码:

树型dp的代码都很像,就是把状态转移改改
这个代码貌似有点问题,我还在改(为什么牛客oj提交不上)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=1050;
vector<int>edge[maxn];
int ans=0;
int dp[maxn][4];
void dfs(int u,int fa)
{
    dp[u][1]=1;
    ans=max(ans,dp[u][1]); 
    for(int v:edge[u])
    {
        if(v==fa)continue;
        dfs(v,u);
        dp[u][1]+=max(dp[v][1],dp[v][0]);
        dp[u][0]+=dp[v][1];
    }
}
int n;
void init()
{
    memset(dp,0,sizeof(dp));
    for(int i=0;i<=n;i++)edge[i].clear();
}
int main()
{

    while(cin>>n)
    {
        init();

        for(int i=1;i<=n;i++)
        {
            int u,v,d;
            scanf("%d:(%d)",&u,&d);
            for(int i=1;i<=d;i++)
            {
                cin>>v;
                edge[u].push_back(v);
                edge[v].push_back(u);
            }

        }
        dfs(0,-1);
        cout<<min(dp[0][0],dp[0][1])<<endl;
    }

    return 0;
}
全部评论

相关推荐

昨天 22:35
门头沟学院 Java
投递华为HUAWEI等公司7个岗位
点赞 评论 收藏
分享
不知道怎么取名字_:两个方向 1.简历针对性准备下 2.面试前也需要准备的 主要还是要看各个公司需求,看公司行业和岗位描述,那里面已经写了对技术的需求,一份简历,不可能和所有嵌入式岗位都匹配的
投递北京经纬恒润科技股份有限公司等公司7个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务