hdu 1054 Strategic Game (简单树形DP)
Strategic Game
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10035 Accepted Submission(s): 4691
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:
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)
题目大意:
给你一棵树,问你最少占几个点,就可以覆盖所有边。(占住某个点,由这点出发的所有边都称作被覆盖)
树形DP基础题。
dp[i][0]表示以i为根节点的子树,在不占i的情况下,最少需要占多少个点;
dp[i][1]表示以i为根节点的子树,在占i的情况下,最少需要占多少个点;
则状态转移方程:
dp[i][0]=∑dp[son][1];
dp[i][1]=∑min(dp[son][0],dp[son][1]);
可见是由下至上转移的,所以DFS就OK啦。
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm> using namespace std; const int maxn=; int to[maxn*+];
int nex[maxn*+];
int head[maxn*+]; int dp[maxn+][];
int vis[maxn+]; void dfs(int x)
{
vis[x]=;
bool flag=;
for(int i=head[x];i!=-;i=nex[i])
{
if(!vis[to[i]])
{
dfs(to[i]);
flag=;
}
}
if(!flag)
{
dp[x][]=;
return;
}
for(int i=head[x];i!=-;i=nex[i])
{
dp[x][]+=dp[to[i]][];
dp[x][]+=min(dp[to[i]][],dp[to[i]][]);
}
dp[x][]+=;
} int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(head,-,sizeof(head));
for(int i=,a,b,c,cnt=;i<=n;i++)
{
scanf("%d:(%d)",&a,&c);
while(c--)
{
scanf("%d",&b);
to[cnt]=a;nex[cnt]=head[b];head[b]=cnt++;
to[cnt]=b;nex[cnt]=head[a];head[a]=cnt++;
}
} memset(dp,,sizeof(dp));
memset(vis,,sizeof(vis));
dfs(); printf("%d\n",min(dp[][],dp[][]));
}
return ;
}
还有一道类似的入门题,hdu1520,附ac代码。
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm> using namespace std; const int maxn=; int weight[maxn+];
int isson[maxn+]; int to[maxn+];
int nex[maxn+];
int head[maxn+]; int dp[maxn][]; void dfs(int x)
{
if(head[x]==-)
{
dp[x][]=;
dp[x][]=weight[x];
//printf("%d %d %d\n%d %d %d\n",x,0,dp[x][0],x,1,dp[x][1]);
return;
}
for(int i=head[x];i!=-;i=nex[i])
dfs(to[i]);
for(int i=head[x];i!=-;i=nex[i])
{
dp[x][]+=max(dp[to[i]][],dp[to[i]][]);
dp[x][]+=dp[to[i]][];
}
dp[x][]+=weight[x];
//printf("%d %d %d\n%d %d %d\n",x,0,dp[x][0],x,1,dp[x][1]);
} int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=;i<=n;i++)
scanf("%d",weight+i);
memset(isson,,sizeof(isson));
memset(head,-,sizeof(head));
for(int i=,a,b,cnt=;i<=n;i++)
{
scanf("%d%d",&a,&b);
if(i==n)
break;
to[cnt]=a;
nex[cnt]=head[b];
head[b]=cnt++;
isson[a]=;
}
int origin;
for(int i=;i<=n;i++)
if(!isson[i])
{
origin=i;
break;
}
//printf("%d\n",origin); memset(dp,,sizeof(dp));
dfs(origin); printf("%d\n",max(dp[origin][],dp[origin][]));
}
return ;
}
hdu 1054 Strategic Game (简单树形DP)的更多相关文章
- HDU 1054 Strategic Game(树形DP)
Problem Description Bob enjoys playing computer games, especially strategic games, but sometimes he ...
- hdu 1054 Strategic Game 经典树形DP
Strategic Game Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU 1054 Strategic Game(树形DP)
Strategic Game Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- hdu 4514 并查集+树形dp
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- HDU - 1054 Strategic Game(二分图最小点覆盖/树形dp)
d.一颗树,选最少的点覆盖所有边 s. 1.可以转成二分图的最小点覆盖来做.不过转换后要把匹配数除以2,这个待细看. 2.也可以用树形dp c.匈牙利算法(邻接表,用vector实现): /* 用ST ...
- HDU 1054 Strategic Game (树形dp)
题目链接 题意: 给一颗树,用最少的点覆盖整棵树. 每一个结点可以防守相邻的一个边,求最少的点防守所有的边. 分析: 1:以当前节点为根节点,在该节点排士兵守护道路的最小消耗.在这种情况下,他的子节点 ...
- HDU 1054 Strategic Game(最小点覆盖+树形dp)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=106048#problem/B 题意:给出一些点相连,找出最小的点数覆盖所有的 ...
- hdu 1520Anniversary party(简单树形dp)
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
随机推荐
- fastjson 1.2.24反序列化导致任意命令执行漏洞分析记录
环境搭建: 漏洞影响版本: fastjson在1.2.24以及之前版本存在远程代码执行高危安全漏洞 环境地址: https://github.com/vulhub/vulhub/tree/master ...
- 移动端vue页面禁止移动/滚动
当需要在移动端中禁止页面滚动,加入:@touchmove.prevent即可,例子如下 <template> <div @touchmove.prevent> <h3 c ...
- JavaScript笔记二
1.表格 - 在网页中可以通过表格来表示一些格式化的数据 - 表格相关的标签 - <table> 用来创建一个表格 - <tr> 表示表格中的一行 - <th> 表 ...
- wake on lan定时开机部署
在Linux下通过Wake On LAN实现网络唤醒远程开机 我们经常有这样的场景或需求,人在外面,需要将家里的机器或公司的机器开启,进行远程控制操作. 有几种方式可以实现远程开机,一是通过主板的来电 ...
- springboot+微信小程序实现微信支付【统一下单】
说明: 1)微信支付必须有营业执照才可以申请 2)微信支付官方api是全套的,我这是抽取其中的统一下单api,做了一个简单的封装 首先看看微信支付 商户系统和微信支付系统主要交互: 1.小程序内调用登 ...
- SpringBoot源码学习系列之嵌入式Servlet容器
目录 1.博客前言简单介绍 2.定制servlet容器 3.变换servlet容器 4.servlet容器启动原理 SpringBoot源码学习系列之嵌入式Servlet容器启动原理 @ 1.博客前言 ...
- 一文看尽Java-并发编程知识点
一.前言 从7月份开始一直加班比较多,一直到双11结束,博客没跟上写,接下来写一点总结性的东西,比如Java并发编程总结.Mybatis源码总结.Spring源码和基础知识总结,首先来看下并发 ...
- Hudi基本概念
Apache Hudi(发音为"Hoodie")在DFS的数据集上提供以下流原语 插入更新 (如何改变数据集?) 增量拉取 (如何获取变更的数据?) 在本节中,我们将讨论重要的概念 ...
- Python面试的一些心得,与Python练习题分享【华为云技术分享】
版权声明:本文为CSDN博主「华为云」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/devcloud/arti ...
- 大型情感剧集Selenium:1_介绍 #华为云·寻找黑马程序员#
学习selenium能做什么? 很多书籍.文章中是这么定义selenium的: Selenium 是开源的自动化测试工具,它主要是用于Web 应用程序的自动化测试,不只局限于此,同时支持所有基于web ...