Strategic Game

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2925    Accepted Submission(s): 1222

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 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:

 
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
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
int brother,child;
int yes;//该点放士兵
int no; //该点不放士兵
}tree[];
int n,i,j,k,root,num,origin; void dfs(int root)
{
int child=tree[root].child;
while(child>)
{
dfs(child);
tree[root].yes+=min(tree[child].yes,tree[child].no);
//父亲结点放置了,儿子结点可以放置也可以不放置
tree[root].no+=tree[child].yes;
//父亲结点没有放置,儿子结点必须放置
child=tree[child].brother;
}
}
int main()
{
while(~scanf("%d",&n))
{
for(i=;i<=n;i++)
{
tree[i].brother=tree[i].child=;
tree[i].yes=;
tree[i].no=;
}
for(int t=;t<=n;t++)
{
scanf("%d:(%d)",&root,&num);
root++;
if (t==) origin=root;
for(i=;i<=num;i++)
{
int x;
scanf("%d",&x);
x++;
tree[x].brother=tree[root].child;
tree[root].child=x;
}
}
dfs(origin);
printf("%d\n",min(tree[origin].yes,tree[origin].no));
} return ;
}

代码二:

dproot[ i ]表示以i为根的子树,在i上放置一个士兵,看守住整个子树需要多少士兵。

all[ i ]表示看守住整个以i为根的子树需要多少士兵。

状态转移方程:

叶子节点: dproot[k] =1; all[k] = 0;

非叶子节点: dproot[i] = 1 + ∑all[j](j是i的儿子);

      all[i] = min( dproot[i], ∑dproot[j](j是i的儿子) );

#include <iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int M=+;
int dproot[M],all[M];
int i,n,x,y,k;
vector<int> v[M];
void dfs(int x,int fa)
{
int tmp=;
for(int i=;i<v[x].size();i++)
{
int k=v[x][i];
if (k==fa) continue;
dfs(k,x);
dproot[x]+=all[k];
tmp=tmp+dproot[k];
}
all[x]=min(dproot[x],tmp);
return;
}
int main()
{
while(~scanf("%d",&n))
{
for(i=;i<n;i++)
{
v[i].clear();
all[i]=;
dproot[i]=;
}
for(int t=;t<=n;t++)
{
scanf("%d:(%d)",&x,&y);
for(i=;i<=y;i++)
{
scanf("%d",&k);
v[x].push_back(k);
v[k].push_back(x);
}
}
dfs(,-);
printf("%d\n",all[]);
}
return ;
}

  

Source

HDU 1054 Strategic Game(树形DP)的更多相关文章

  1. HDU 1054 Strategic Game (树形dp)

    题目链接 题意: 给一颗树,用最少的点覆盖整棵树. 每一个结点可以防守相邻的一个边,求最少的点防守所有的边. 分析: 1:以当前节点为根节点,在该节点排士兵守护道路的最小消耗.在这种情况下,他的子节点 ...

  2. hdu 1054 Strategic Game(tree dp)

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  3. hdu1054 Strategic Game 树形DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054 思路:树形DP,用二分匹配也能解决 定义dp[root][1],表示以root 为根结点的子树且 ...

  4. HDU - 1054 Strategic Game(二分图最小点覆盖/树形dp)

    d.一颗树,选最少的点覆盖所有边 s. 1.可以转成二分图的最小点覆盖来做.不过转换后要把匹配数除以2,这个待细看. 2.也可以用树形dp c.匈牙利算法(邻接表,用vector实现): /* 用ST ...

  5. HDU 1054 Strategic Game(树形DP)

    Problem Description Bob enjoys playing computer games, especially strategic games, but sometimes he ...

  6. hdu 1054 Strategic Game (简单树形DP)

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. HDU 1054 Strategic Game(最小点覆盖+树形dp)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=106048#problem/B 题意:给出一些点相连,找出最小的点数覆盖所有的 ...

  8. Strategic game(树形DP入门)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054 题目大意:一棵树,要放置哨兵,要求最少放置多少哨兵能监视到所有的结点 题目分析: 放置哨兵无非两 ...

  9. POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题

    一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...

  10. POJ1463:Strategic game(树形DP)

    Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot f ...

随机推荐

  1. C# 语言规范_版本5.0 (第5章 变量)

    1. 变量 变量表示存储位置.每个变量都具有一个类型,用于确定哪些值可以存储在该变量中.C# 是一种类型安全的语言,C# 编译器保证存储在变量中的值总是具有合适的类型.通过赋值或使用 ++ 和 ‑‑ ...

  2. [ An Ac a Day ^_^ ] hdu 1003 dp

    超时还有可能是数组开小了…… #include<stdio.h> #include<iostream> #include<algorithm> #include&l ...

  3. 经典dp 最长公共子序列

    首先,说明一下子序列的定义…… 一个序列A={a1,a2,a3,...,an},从中删除任意若干项,剩余的序列叫A的一个子序列. 很明显(并不明显……),子序列……并不需要元素是连续的……(一开始的时 ...

  4. Openjudge-计算概论(A)-整数的个数

    描述: 给定k(1<k<100)个正整数,其中每个数都是大于等于1,小于等于10的数.写程序计算给定的k个正整数中,1,5和10出现的次数.输入输入有两行:第一行包含一个正整数k,第二行包 ...

  5. maven入门(下)

    Apache Maven 入门篇(下) 作者:George Ma 第一篇文章大概的介绍了一下Apache Maven以及它的下载和安装,并且运行了一个简单的示例.那么在对maven有了一点接触后,接下 ...

  6. onbeforeunload与a标签在IE中的冲突bug(转载)

    onbeforeunload与a标签在IE中的冲突bug   onbeforeunload 是window的一个事件,目前Firefox,IE都支持,主要用来提示用户是否真的要离开该页面,通常在一些比 ...

  7. c# 操作word demo

    /// <summary> /// 新创建word /// </summary> /// <param name="fileSaveDirectory" ...

  8. 基于Flash与window平台本地程序通信实现媒体流发布

    0 Web场景下的媒体流发布可以采用Flash原生API实现,但是Flash H264视频压缩参数不可控.音频无法AAC编码,所以一般采用浏览器插件方式,但是浏览器插件有版本兼容问题.不稳定,所以可以 ...

  9. bat自动创建文件夹(以当前时间命名)

    先cmd中查看当前的日期和时间: @echo off color 0a set dt=%date%%time% echo %dt%pause 1.使用截取进行命名(时间为12小时制时命名会出现空格,不 ...

  10. DB9_公头_母头_串口引脚定义及RS-232串口线制作方法

    RS-232连接线制作方法 材料及工具 一根双绞线(8芯).一个标准RJ45头.一个DB9孔型插头.一把RJ45专用工具.一个电烙铁及若干焊锡. 引脚定义 按以下管脚定义制作RJ45端头:I表示网络视 ...