树形dp(最小支配集)
http://poj.org/problem?id=3659
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
const int M=1e4+;
const int inf=0x3f3f3f3f;
vector<int>e[M];
int dp[M][];
void dfs(int u ,int f){
dp[u][]=;
int minn=inf;
int flag=;
for(int i=;i<e[u].size();i++){
int v=e[u][i];
if(v==f)
continue;
dfs(v,u);
dp[u][]+=min(dp[v][],min(dp[v][],dp[v][]));
dp[u][]+=min(dp[v][],dp[v][]);
if(dp[v][]<=dp[v][]){
flag=;
dp[u][]+=dp[v][];
}
else{
minn=min(minn,dp[v][]-dp[v][]);
dp[u][]+=dp[v][];
}
}
if(flag)
dp[u][]+=minn;
}
int main(){
int n;
scanf("%d",&n);
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
dfs(,-);
printf("%d",min(dp[][],dp[][]));
return ;
}
解题:可以用动态规划,也可以用最小支配集。
一、现在先说用动态规划的思路:
根据题意知道每个节点有三种状态:
1、点i建塔,i的所有孩子都覆盖,用dp[i][0]表示;
2、点i不建塔,i和i的所有孩子都覆盖,用dp[i][1]表示;
3、点i不建塔,i不覆盖,i的所有孩子都覆盖,用dp[i][2]表示;
如果这样不好理解那么这样理解可能容易一点(参考别人的):覆盖i,要么是父节点覆盖,要么是自己,要么是孩子,所以三种状态(和上面的对应):
1、点i自己覆盖自己,i的所有孩子都覆盖,用dp[i][0]表示;
2、点i被自己的孩子覆盖,i和i的所有孩子都覆盖,用dp[i][1]表示;
3、点i被父节点覆盖,i的所有孩子都覆盖,用dp[i][2]表示;
那么动态转移方程就是(v是i的孩子):
dp[i][0]+=min(dp[v][0],dp[v][1],dp[v][2]);
dp[i][2]+=min(dp[v][0],dp[v][1]);
对于dp[i][1],要考虑全面,也就是说:必须要有一个孩子建塔,才能保证i被覆盖(Min=sum(min(dp[v][0]-dp[i][1])),也就是当所有孩子的dp[v][0]>dp[v][i]时,Min表示他们差值最小的那个差值)。
所以方程是dp[i][1]+=min(dp[v][0],dp[1])(至少存在一个孩子的dp[v][0]<=dp[v][1],否则要dp[i][1]+=Min);
原文:https://blog.csdn.net/jiang199235jiangjj/article/details/7878473
树形dp(最小支配集)的更多相关文章
- 树形DP 树的最小支配集,最小点覆盖与最大独立集
最小支配集: 从V中选取尽量少的点组成一个集合,让V中剩余的点都与取出来的点有边相连. (点) 最小点覆盖: 从V中选取尽量少的点组成一个集合V1,让所有边(u,v)中要么u属于V1,要么v属于V1 ...
- 求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp
目录 求树的最大独立集,最小点覆盖,最小支配集 三个定义 贪心解法 树形DP解法 (有任何问题欢迎留言或私聊&&欢迎交流讨论哦 求树的最大独立集,最小点覆盖,最小支配集 三个定义 最大 ...
- 树形DP求树的最小支配集,最小点覆盖,最大独立集
一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合时此点还需要被覆盖,被覆盖也有两种状态,即被子节点覆盖或者被父节点覆盖.总结起来就是三种状态,现对 ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
- POJ 3398 Perfect Service --最小支配集
题目链接:http://poj.org/problem?id=3398 这题可以用两种上述讲的两种算法解:http://www.cnblogs.com/whatbeg/p/3776612.html 第 ...
- Cell Phone Networ (树形dp-最小支配集)
目录 Cell Phone Networ (树形dp-最小支配集) 题意 思路 题解 Cell Phone Networ (树形dp-最小支配集) Farmer John has decided to ...
- POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法
POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...
- 求解任意图的最小支配集(Minimun Dominating Set)
给定一个无向图G =(V,E),其中V表示图中顶点集合,E表示边的集合.G的最小控制顶点集合为V的一个子集S∈V:假设集合R表示V排除集合S后剩余顶点集合,即R∩S=∅,R∪S=V:则最小控制顶点集合 ...
- POJ 3398 Perfect Service(树型动态规划,最小支配集)
POJ 3398 Perfect Service(树型动态规划,最小支配集) Description A network is composed of N computers connected by ...
随机推荐
- .equal()和==的区别
1.首先,equal和==最根本的区别在于equal是一个方法,而==是一个运算符. 2.一般来说,==运算符比较的是在内存中的物理地址,.equal()比较的是哈希算法值是否相等(即hashcode ...
- POJ 1837:Balance 天平DP。。。
Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 11878 Accepted: 7417 Descript ...
- JavaScript—面向对象 贪吃蛇_3 蛇对象
蛇对象 function Snake(element) { this.width = 20 this.height = 20 //蛇身 位置 颜色 this.body = [ {x: 6, y: 4, ...
- C++构造函数概念作用
作用: 对对象进行初始化,如给成员变量赋初值,而不用专门再写初始化函数. 防止有些对象没被初始化就使用,导致程序出错. 要求: 名字与类名相同,可以有参数,但不能有返回值(void也不行) 编译时: ...
- python装饰器类
from functools import wraps class logit(object): def __init__(self, logger): self.logger = logger de ...
- 干货 | IP高防使用配置
一.知识简介 DoS(Denial of Service),即拒绝服务攻击.该攻击是利用目标系统网络服务功能缺陷或者直接消耗其系统资源,目的是使该目标客户的系统不可用,无法提供正常的服务. DDoS( ...
- 13)编写一个子类SnakeCtrl来继承基类
1)首先是创建子类SnakeCtrl 2) 添加那个SnakeCtrl子类 3)出来了SnakeCtrl的基本样子 4)简单实现: ①改编那个SnakeCtrl.h中的内容: #pragma ...
- linux的centos设置静态网络
这个是该自己的网络排至,具体的分析,自己以后再研究 http://www.centoscn.com/CentOS/config/2015/0227/4753.html
- UML-如何进行对象设计?
之前的章节,学过了OOA,以及交互图+类图.本章主要讲述OOD.OOD就是面向对象设计,那如何进行对象设计? 概览 1.输入制品 注:这些制品并非都必要. 2.活动 1).针对输入的制品,采用什么样的 ...
- spark shc hbase 超时问题 hbase.client.scanner.timeout.period 配置
异常信息 20/02/27 19:36:21 INFO TaskSetManager: Starting task 17.1 in stage 3.0 (TID 56, 725.slave.adh, ...