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

Description

Farmer John has decided to give each of his cows a cell phone in hopes to encourage their social interaction. This, however, requires him to set up cell phone towers on his N (1 ≤ N ≤ 10,000) pastures (conveniently numbered 1..N) so they can all communicate.

Exactly N-1 pairs of pastures are adjacent, and for any two pastures A and B (1 ≤ AN; 1 ≤ BN; AB) there is a sequence of adjacent pastures such that A is the first pasture in the sequence and B is the last. Farmer John can only place cell phone towers in the pastures, and each tower has enough range to provide service to the pasture it is on and all pastures adjacent to the pasture with the cell tower.

Help him determine the minimum number of towers he must install to provide cell phone service to each pasture.

Input

* Line 1: A single integer: N
* Lines 2..N: Each line specifies a pair of adjacent pastures with two space-separated integers: A and B

Output

* Line 1: A single integer indicating the minimum number of towers to install

Sample Input

5
1 3
5 2
4 3
3 5

Sample Output2
题目大意:就是给你一个树状结构,每一个节点可以看守住它自己以及与他相邻的节点,问你最少需要多少个节点
思路分析:首先是树的建立,这是一个无向图,可以用链式前向星来进行见图
我也是现学现卖,这篇博客不错http://blog.csdn.net/acdreamers/article/details/16902023
见图之后就是确定状态以及状态转移方程

•①dp[i][0]:选点i,并且以点i为根的子树都被覆盖了。

•②dp[i][1]:不选点i,i被其儿子覆盖
•③dp[i][2]:不选点i,i没有被子节点覆盖(被其父亲覆盖)
•第二步:确定状态转移方程
•dp[i][0]=1+Σmin(dp[u][0],dp[u][1],dp[u][2]) (u是i的儿子)
•dp[i][2]=Σ(dp[u][1])
•对于dp[i][1]的讨论稍微复杂一点——他的所有儿子里面必须有一个取dp[u][1]
• 那么:if(i没有子节点)dp[i][1]=INF
•else dp[i][1]=Σmin(dp[u][0],dp[u][1])+inc
•其中对于inc有:
•if(上面式子中的Σmin(dp[u][0],dp[u][1])中包含某个dp[u][0])inc=0;
•else inc=min(dp[u][0]-dp[u][1])。
代码:

/*
poj3659
树的最小支配集
树状DP
by xjy*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=+;
struct node//链式前向星存图
{
int to;
int next;
};
node edge[*maxn];//因为无向,所以同一条边会存两次
bool vis[maxn];
int head[maxn];
int dp[maxn][];//状态,对于树上的任意一个点,其合法状态有三种,被自身覆盖,被父节点覆盖,被子节点覆盖
int n;
int tot;
const int inf=0xfffff;
void add(int x,int y)
{
edge[tot].to=y;//这条边的指向
edge[tot].next=head[x];//x连的上一条边
head[x]=tot++;//记录该点这次出现的边的位置
}
void dfs(int nod)
{
bool flag=true;//在对dp[nod][1]的处理上要用到
dp[nod][]=,dp[nod][]=dp[nod][]=;//初始化
vis[nod]=true;//标记数组,通过标记,使得搜索只能从上往下搜,变成了一棵有向树
int Min=inf;
int v;
for(int i=head[nod];i!=-;i=edge[i].next)//head[nod]存的是最后一次出现该节点的边的下标
{
v=edge[i].to;//这条边指向的点
if(!vis[v])
{
dfs(v);
dp[nod][]+=min(dp[v][],min(dp[v][],dp[v][]));
dp[nod][]+=min(dp[v][],dp[v][]);
if(dp[v][]<=dp[v][])
{
flag=false;
dp[nod][]+=dp[v][];
}
else
{
dp[nod][]+=dp[v][];
Min=min(Min,dp[v][]-dp[v][]);
}
}
}
if(flag) //所有子节点都没有放置,不合题意,选择最优的进行放置
dp[nod][]+=Min;//对于叶子节点,dp[i][1]=inf:
}
void init()
{
int a,b;
memset(head,-,sizeof(head));
memset(vis,false,sizeof(vis));
tot=;
for(int i=;i<n;i++)
{
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
dfs();//因为是无向图,选择任意一个节点作为根节点
printf("%d\n",min(dp[][],dp[][]));//选1作为整个树的根节点,不可能出现其被其父节点覆盖的情况
}
return ;
}

poj3659树状DP的更多相关文章

  1. 树状DP (poj 2342)

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

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

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

  3. poj 2342 Anniversary party_经典树状dp

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

  4. 树状DP HDU1520 Anniversary party

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

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

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

  6. 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 ...

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

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

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

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

  9. 洛谷P1122 最大子树和 (树状dp)

    题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...

随机推荐

  1. js_day2

    1)<script src="dsad.js"> 不是  scr= 2)

  2. cmd编译运行Java文件详解

    ①准备工作 首先用记事本编写HelloWorld.java放至G:\Javaspace路径 public class HelloWorld{ public static void main(Strin ...

  3. Mysql中的 的 Cascade ,NO ACTION ,Restrict ,SET NULL

    转载自:http://blog.163.com/inflexible_simple/blog/static/1676946842011616102543931/ 外键约束对子表的含义:    如果在父 ...

  4. 无法更新 EntitySet“Ips_Articles”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> 元素中没有支持当前操作的 <InsertFunction> 元素。

    今天我在使用ef的时候,发现了这样的报错. 无法更新 EntitySet“Ips_Articles”,因为它有一个 DefiningQuery,而 <ModificationFunctionMa ...

  5. CFLAGS/CPPFLAGS/CXXFLAGS in Makefile介绍

    先来看一张关于Makefile中的常见预定义变量. CFLAGS 表示用于 C 编译器的选项,CXXFLAGS 表示用于 C++ 编译器的选项.这两个变量实际上涵盖了编译和汇编两个步骤.大多数程序和库 ...

  6. Python新手学习基础之条件语句——elif语句

    elif语句 (相当于C语言的else if) 在Python中,当我们需要有更多的判断条件时,我们往往会使用另外一种语法表达,即使用elif: if 判断条件1: 执行语句1 elif 判断条件2: ...

  7. MySQL数据库中日期中包涵零值的问题

    默认情况下MySQL是可以接受在日期中插入0值,对于现实来说日期中的0值又没有什么意义.调整MySQL的sql_mode变量就能达到目的. set @@global.sql_mode='STRICT_ ...

  8. FJ省队集训DAY3 T1

    思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分. 因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的 ...

  9. [置顶] 【原创分享】嵌入式linux应用之内核移植定制篇-前篇(linux-3.8.12 mini2440)--20130824

    移植的话其实很早就做过了,不过那时用的友善定制的老版本2.6.32 驱动什么的全部弄好了,仅仅用默认配置而已.基本不用改动什么,很简单. 内核更新其实非常的快,今天我就用个3.8.12来移植. 当然, ...

  10. 什么时候该使用NoSQL存储数据库?

    原文地址:http://www.jdon.com/39240 文章总结以下几点:1.频繁写,很少读统计数据,比如点击率,应该使用基于内存的in-memory的key/value存储数据库如Redis, ...