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 ...
随机推荐
- vuejs中的回车事件
@keyup.enter.native="事件名称"
- Obtaining the backtrace - libunwind
Sometimes when working on a large project, I find it useful to figure out all the places from which ...
- 20191114-2 Beta事后诸葛亮会议
此作业要求:http://edu.cnblogs.com/campus/nenu/2019fall/homework/10005 组名:扛把子 组长:孙晓宇 组员:宋晓丽.梁梦瑶.韩昊.刘信鹏 扛把子 ...
- 2011-11-14:命令执行漏洞防御,PHP反序列化漏洞产生原因,笔记
命令执行漏洞防御尽量不要使用系统执行命令在进入执行命令函数方法之前,变量一定要做好过滤,对敏感字符进行转义在使用动态函数之前,确保使用的函数是指定的函数之一对PHP语言来说,不能完全控制的危险函数最好 ...
- Dart Learn Notes 03
操作符 dart 有一套自己定义的操作符: 这里我就不再写了,直接copy一份官网的. 如果有过编程基础,上边展示的操作符应该都不陌生. 算术运算符 加: + 减: - 乘: * 除: / 取余: % ...
- spring日志体系浅析(spring 5.x)
日志是进行软件开发必不可少的一项功能,目前流行着很多开源日志库,比如log4j.log4j2.logback.JDK Logging.commons-logging.slf4j等. 几种日志产品的介绍 ...
- 公众号在线Markdown编辑器,支持公式
公众号排版不支持Markdown,用自带的富文本编辑器排版出来的格式十分丑陋,尤其是公式,竟然连"Mathjax"都不支持,但好在支持"带格式复制",也即可以将 ...
- 小白学 Python 爬虫(8):网页基础
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 【Android - 组件】之Activity的启动模式
Activity的启动模式目前有四种:standard.singleTop.singleTask 和 singleInstance. 1.standard standard 是标准模式,也是系统的默认 ...
- Linux权限基础
Linux权限基础 四种权限大类 基本权限 特殊权限 隐藏权限 file ACL权限 三种基本权限 r(read) 读是基本权限,没有读权限其他的一切操作都会被限制 读 4 w(write) 写 2 ...