B - 树形dp

Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u

Submit Status

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.

For example for the tree:

the solution is one soldier ( at the node 1).

Input

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.

Output

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:

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
题目大意:给你一个树状结构,每一个节点都可以放置士兵,可以看守住与 该节点相邻的所有边,问你最少需要多少个节点。
思路分析:树的最小点覆盖问题,首先确定状态f[i[0]表示在根节点i上不放置士兵看守住这棵子树需要的最少士兵,f[i][0]
则代表根结点i上不放置士兵看守住所需要的最少士兵,状态转移方程f[i][1]+=min(f[j][1],f[j][0]),f[i][0]+=f[j][1]
初始化f[i][[1]=1,f[i][0]=0; 代码:
/*树的最小点覆盖
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1500+10;
int fat[maxn];
int dp[maxn][2];
bool vis[maxn];//标记
int n;
void dfs(int x)
{
//cout<<x<<endl;
vis[x]=true;
dp[x][1]=1;
dp[x][0]=0;
for(int i=0;i<n;i++)
{
if(!vis[i]&&fat[i]==x)
{
dfs(i);
dp[x][1]+=min(dp[i][0],dp[i][1]);//子节点可放可不放
dp[x][0]+=dp[i][1];
}
}
}
int main()
{
int r,num;
int a;
int i;
while(scanf("%d",&n)!=EOF)
{
// cout<<n<<endl;
memset(fat,0,sizeof(fat));
memset(vis,false,sizeof(vis));
for(int k=0;k<n;k++)
{
scanf("%d:(%d)",&r,&num);
//cout<<r<<" "<<num<<endl;
for(int i=1;i<=num;i++)
{
scanf("%d",&a);
fat[a]=r;
// cout<<a<<endl;
}
}
// for(int i=0;i<n;i++)
//cout<<fat[i]<<endl;
for(i=0;i<n;i++)
{
if(!fat[i])
{
//cout<<i<<endl;
dfs(i);
cout<<min(dp[i][0],dp[i][1])<<endl;
break;
}
} }
return 0;
}

  思考了下我这样写是有弊端的,这是一个无向图,然而我建树的时候默认了先出的数为根,后出的为子节点,这样是不对的。。。然而数据水过,自己又用链式前向星

存图写了一些,效率大大提高

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=+;
struct node
{
int to;
int next;
};
node edge[*maxn];
int head[maxn];
int dp[maxn][];
bool vis[maxn];//把一个无向 图变成有向图
int tot;
int n;
void add(int x,int y)
{
edge[tot].to=y;
edge[tot].next=head[x];
head[x]=tot++;
}
void init()
{
memset(head,-,sizeof(head));
memset(vis,false,sizeof(vis));
tot=;
int r,num;
int a;
for(int i=;i<n;i++)
{
scanf("%d:(%d)",&r,&num);
for(int i=;i<num;i++)
{
scanf("%d",&a);
add(a,r);
add(r,a);
}
}
}
void dfs(int nod)
{
vis[nod]=true;
dp[nod][]=,dp[nod][]=;
for(int i=head[nod];i!=-;i=edge[i].next)
{
int v=edge[i].to;//这条边指向的点
if(!vis[v])
{
dfs(v);
dp[nod][]+=min(dp[v][],dp[v][]);
dp[nod][]+=dp[v][];
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
dfs();
printf("%d\n",min(dp[][],dp[][]));
}
}

hdu1054 树状dp的更多相关文章

  1. 树状DP (poj 2342)

    题目:Anniversary party 题意:给出N各节点的快乐指数,以及父子关系,求最大快乐指数和(没人职员愿意跟直接上司一起玩): 思路:从底向上的树状DP: 第一种情况:第i个员工不参与,F[ ...

  2. poj3659树状DP

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6273   Accepted: 225 ...

  3. hdu 1561 The more, The Better_树状dp

    题目链接 题意:给你一棵树,各个节点都有价值(除根节点),从根节点出发,选择m个节点,问最多的价值是多小. 思路:很明显是树状dp,遍历树时背包最优价值,dp[i][k]=max{dp[i][r]+d ...

  4. poj 2342 Anniversary party_经典树状dp

    题意:Ural大学有n个职员,1~N编号,他们有从属关系,就是说他们关系就像一棵树,父节点就是子节点的直接上司,每个职员有一个快乐指数,现在要开会,职员和职员的直接上司不能同时开会,问怎才能使开会的快 ...

  5. 树状DP HDU1520 Anniversary party

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:职员之间有上下级关系,每个职员有自己的happy值,越高在派对上就越能炒热气氛.但是必须是 ...

  6. [Codeforces743D][luogu CF743D]Chloe and pleasant prizes[树状DP入门][毒瘤数据]

    这个题的数据真的很毒瘤,身为一个交了8遍的蒟蒻的呐喊(嘤嘤嘤) 个人认为作为一个树状DP的入门题十分合适,同时建议做完这个题之后再去做一下这个题 选课 同时在这里挂一个选取节点型树形DP的状态转移方程 ...

  7. HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)

    Description A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...

  8. poj2486--Apple Tree(树状dp)

    Apple Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7789   Accepted: 2606 Descri ...

  9. 洛谷P2015 二叉苹果树(树状dp)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

随机推荐

  1. C#自定义Attribute值的获取与优化

    C#自定义Attribute值的获取是开发中会经常用到的,一般我们的做法也就是用反射进行获取的,代码也不是很复杂. 1.首先有如下自定义的Attribute [AttributeUsage(Attri ...

  2. web标准(复习)--1

    XHTML CSS基础知识 一.xhtml css基础知识首先说一下我们这节课的知识点 1.文档类型 2.语言编码 3.html标签 4.css样式 5.css优先级 6.css盒模型组成 1)文档类 ...

  3. jQuery Mobile 网格

    在列容器中,根据不同的列数,子元素可设置类 ui-block-a|b|c|d|e.这些列将依次并排浮动. 网格中的列是等宽的(总宽是 100%),无边框.背景.外边距或内边距. 例: 对于 ui-gr ...

  4. GetMemory 函数解析

    GetMemory函数 代码1: void GetMemory(char *p){ p = (char*)malloc(100);}int main(int argc, char *argv[]){ ...

  5. Linux中的段管理,bss段,data段,

    Linux 的段管理, BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存 ...

  6. Adt 配置注释模板

    点击Window->Preferences->Java->Code Style->Code Templates,如下图所示: 选中,点击右侧的Edit进行编辑.

  7. 页面正在载入js

    页面显示(pageshow)和页面隐藏(pagehide)事件 http://blog.163.com/jiang_tao_2010/blog/static/121126890200911403336 ...

  8. Codeforces 13C Sequence

    http://codeforces.com/contest/13/problem/C 题目大意 给定一个含有N个数的序列,要求你对一些数减掉或者加上某个值,使得序列变为非递减的,问你加减的值的总和最少 ...

  9. 目测ZIP的压缩率

    对word文件,能压到25% 对PDF文件,却只有90% 对压缩文件本身再压缩,几乎没有效果. 考虑到用户一般情况下只有正常的文档,取中位值66%是比较正常的情况,特别是在预估原文件大小的时候.

  10. SQL判断一个数是整数还是小数

    DECLARE @number1 AS numeric(10,2),@number2 AS numeric(10,2) SELECT @number1=10.00,@number2=10.2 SELE ...