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为子树 ...
随机推荐
- 新闻网大数据实时分析可视化系统项目——17、Spark2.X分布式弹性数据集
1.三大弹性数据集介绍 1)概念 2)优缺点对比 2.Spark RDD概述与创建方式 1)概述 在集群背后,有一个非常重要的分布式数据架构,即弹性分布式数据集(resilientdistribute ...
- gitbook简单教程
简介 GitBook 是一个基于 Node.js 的命令行工具,可使用 Github/Git 和 Markdown 来制作精美的电子书.GitBook支持输出以下几种文档格式 静态站点:GitBook ...
- Centos 7 安装与卸载MYSQL5.7
先介绍卸载防止重装 yum方式 查看yum是否安装过mysqlyum list installed mysql*如或显示了列表,说明系统中有MySQL yum卸载 根据列表上的名字 yum remov ...
- 7.8 Varnish Log
- 自己写个tween
public Vector3 begin,end;//起始终止坐标 public float BtoE_time;//用时 float timer,lerp;//计时器和进度值 void Update ...
- ACM-挑战题之排列生成
题目描述:挑战题之排列生成 一自然数N,设N为3,则关于N的字典序排列为123,132,213,231,312,321.对于一个自然数N(1<= N <= 9 ) , 你要做的便是生成它的 ...
- Golang的选择结构-switch语句
Golang的选择结构-switch语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.选择语句应用场景概述 选择结构也称为条件判断,生活中关于判断的场景也非常的多,比如: ( ...
- 全选checkbox只能执行一次的问题
现象:第一次运行,点select all那个checkbox,可以全选,再点一次,也可以全部取消.但是,之后不管怎样点击,都没有用了…… <input type="checkbox&q ...
- cf 763A. Timofey and a tree
呵呵呵,直接判断是不是一个点连起来所有的特殊边(连接2不同颜色的点的边) (一开始还想各种各样奇怪的dfs...垃圾) #include<bits/stdc++.h> #define LL ...
- 利用QRCoder生成二维码
1.项目添加QRCoder.dll 和System.Drawing.dll的引用 2.创建二维码公共处理类(QRCoderHelper.cs) /// <summary> /// 二维码公 ...