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. [ An Ac a Day ^_^ ] CodeForces 468A 24 Game 构造

    题意是让你用1到n的数构造24 看完题解感觉被样例骗了…… 很明显 n<4肯定不行 然后构造出来4 5的组成24的式子 把大于4(偶数)或者5(奇数)的数构造成i-(i-1)=1 之后就是无尽的 ...

  2. Gentoo挂载ntfs的NTFS分区

    内核需要开启的选项 File systems ---> <*> FUSE (Filesystem in Userspace) support 使用NTFS-3G NTFS-3G是一个 ...

  3. markdown 自己搞一个浏览工具

    注意!`下不能有空行 `上也不能有空行 问题未解决 <!DOCTYPE html> <html lang="en"> <head> <me ...

  4. amazeui 搜索 动态

    <!doctype html> <html class="no-js"> <head> <meta charset="utf-8 ...

  5. chapter11_3 字符串缓冲

    逐行地读取一个文件,典型的代码是: local buff= " " for line in io.lines() do buff = buff .. line .. "\ ...

  6. NOIP2011-普及组复赛模拟试题-第一题-NBA总冠军

    题目背景 Background 一年两度的期末考要到来了!!  题目描述 Description   又要到考试了,Ljw决定放松一下,就打开电视,看见了篮球赛,他立即想到了每年的NBA总冠军队伍.由 ...

  7. ios 中Category类别(扩展类)小结

    类别 类别是一种为现有的类添加新方法的方式.利用Objective-C的动态运行时(runtime)分配机制,可以为现有的类添加新方法,这种为现有的类添加新方法的方式称为类别catagory,他可以为 ...

  8. NSBundle、UIImageView和UIButton对比、Xcode文档安装路径、Xcode模拟器安装路径

    1.NSBundle1> 一个NSBundle代表一个文件夹,利用NSBundle能访问对应的文件夹2> 利用mainBundle就可以访问软件资源包中的任何资源3> 模拟器应用程序 ...

  9. ecshop php5.4以上版本错误之preg_replace 替换成 preg_replace_callback

    类似这样的报错: Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instea ...

  10. 【第二篇】学习 android 事件总线androidEventbus之异步事件的传递

    1,不同Activity直接发送Ansy的事件,以及其他任何事件,必须通过 postSticky方式来进行事件的传递,而不能通过post的形式来进行传递:EventBus.getDefault().p ...