POJ - 3659 Cell Phone Network(树形dp---树的最小点支配集)
题意:有N个点,N-1条边,任意两点可达,由此形成了一棵树。选取一个点a,它可覆盖自己以及与自己相邻的点,选取尽量少的点a,使得树中所有点都被覆盖,即求树的最小点支配集。
分析:
1、对于每一个点cur,要想使其被覆盖,有三种情况:
dp[cur][0]---在该点建立塔
dp[cur][1]---在该点的子结点建立塔
dp[cur][2]---在该点的父结点建立塔
2、对于点cur的子结点x,要使其被覆盖:
(1)dp[cur][0] += Min(Min(dp[x][0], dp[x][1]), dp[x][2]);
在cur处建塔的情况下,x可建塔,x的子节点可建塔,x的父结点即cur建塔,三者取最小值,并累加。
(2)dp[cur][2] += Min(dp[x][0], dp[x][1]);
在cur的父结点建塔的情况下,x可建塔,x的子结点可建塔,两者取最小值,并累加。
(3)dp[cur][1] += Min(dp[x][0], dp[x][1]);
在cur的子结点建塔的情况下,至少需要cur的一个子结点建塔cur才能被覆盖,所以对于每一个子结点x,x可建塔,x的子结点可建塔,两者取最小值
与此同时,记录在取最小值的情况下,cur是否有能建塔的子结点,若没有,需要将cur的一个子结点变成可建塔,选取abs(dp[x][1] - dp[x][0])最小的子结点x改变即可。
3、dp[cur][0]最后要加1,因为在cur点要建塔。
#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
const double eps = 1e-8;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 10000 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int N;
vector<int> v[MAXN];
int dp[MAXN][5];
void dfs(int cur, int father){
memset(dp[cur], 0, sizeof dp[cur]);
int len = v[cur].size();
int dif = INT_INF;
bool ok = false;
for(int i = 0; i < len; ++i){
int x = v[cur][i];
if(x == father) continue;
if(dp[x][0] == INT_INF) dfs(x, cur);
dp[cur][0] += Min(Min(dp[x][0], dp[x][1]), dp[x][2]);
dp[cur][2] += Min(dp[x][0], dp[x][1]);
dif = Min(dif, abs(dp[x][1] - dp[x][0]));
if(dp[x][0] < dp[x][1]){
ok = true;
dp[cur][1] += dp[x][0];
}
else{
dp[cur][1] += dp[x][1];
}
}
++dp[cur][0];
if(!ok) dp[cur][1] += dif;
}
int main(){
scanf("%d", &N);
for(int i = 0; i < N - 1; ++i){
int a, b;
scanf("%d%d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
}
memset(dp, INT_INF, sizeof dp);
dfs(1, -1);
printf("%d\n", Min(dp[1][0], dp[1][1]));
return 0;
}
POJ - 3659 Cell Phone Network(树形dp---树的最小点支配集)的更多相关文章
- POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法
POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...
- POJ 3659 Cell Phone Network 最小支配集模板题(树形dp)
题意:有以个 有 N 个节点的树形地图,问在这些顶点上最少建多少个电话杆,可以使得所有顶点被覆盖到,一个节点如果建立了电话杆,那么和它直接相连的顶点也会被覆盖到. 分析:用最少的点覆盖所有的点,即为求 ...
- POJ 3659 Cell Phone Network(树的最小支配集)(贪心)
Cell Phone Network Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6781 Accepted: 242 ...
- 树形DP 树的最小支配集,最小点覆盖与最大独立集
最小支配集: 从V中选取尽量少的点组成一个集合,让V中剩余的点都与取出来的点有边相连. (点) 最小点覆盖: 从V中选取尽量少的点组成一个集合V1,让所有边(u,v)中要么u属于V1,要么v属于V1 ...
- POJ 3659 Cell phone Network (树的最小点覆盖, 树形DP)
题意: 给定一棵树,每个点可以覆盖自己和相邻的点, 求最少要多少个点覆盖图 #include <cstdio> #include <cstring> #include < ...
- POJ 3659 Cell Phone Network (树dp)
题目链接:http://poj.org/problem?id=3659 给你一个树形图,一个点可以覆盖他周围连接的点,让你用最少的点覆盖所有的点. dp[i][0]表示用i点来覆盖,dp[i][1]表 ...
- POJ 3342 Party at Hali-Bula (树形dp 树的最大独立集 判多解 好题)
Party at Hali-Bula Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5660 Accepted: 202 ...
- 树形DP+树状数组 HDU 5877 Weak Pair
//树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
随机推荐
- 使用PYaudio录制音频和视频(自己)
参考:https://blog.csdn.net/zhaoyun_zzz/article/details/84341801 音频录制:简洁版 import pyaudioimport waveimpo ...
- 从植发AI看智能手术机器人的国产化之路
在工作和生活的双重压力下,很多80后乃至90后的青年都"光荣"地加入了"脱发一族".为了拯救发际线或是不变成"地中海",很多人从此走上了寻医 ...
- 关于Android 的内存泄露及分析(转)
一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...
- restfulframework详解
restfulframework详解 第一篇 RESTful规范
- swarm docker-compose.yml NFS 搭建LNMP
列表: 172.16.0.40 (swarm-master) 172.16.0.160 (swarm-worker) 172.16.0.170 (swarm-worker) 1 ...
- Prime Ring Problem素数环(HDU1016)
Prime Ring Problem 思路:先看成一条链,往里头填数,满足任意相邻两数和为质数(这可以打表预处理出40以内的所有质数,扩展的时候枚举),填完了后检查首尾是否满足条件.字典序可以采用扩展 ...
- ROS大型工程学习(一) 必须了解的基本文件
一.Cmake文件 阅读工程,首先点开CMakeLists 文件,会定义一些库和可执行文件.首先看可执行文件,rosrun的就是这个节点navigator add_executable(navigat ...
- nginx location语法解释
1.没有修饰符 表示:必须以指定模式开始,如: 默认模式 server { server_name baidu.com; location /abc { …… } } htt ...
- PyTorch自动微分基本原理
序言:在训练一个神经网络时,梯度的计算是一个关键的步骤,它为神经网络的优化提供了关键数据.但是在面临复杂神经网络的时候导数的计算就成为一个难题,要求人们解出复杂.高维的方程是不现实的.这就是自动微分出 ...
- spring mvc绑定参数之日期类型转换
问题复现步骤: 1.提交表单,参数为: 2.接收参数类型为product实体类,如下 3.错误日志如下: org.springframework.validation.BindException: o ...