树的最小支配集 E - Cell Phone Network POJ - 3659 E. Tree with Small Distances
E - Cell Phone Network
题目大意:
给你一棵树,放置灯塔,每一个节点可以覆盖的范围是这个节点的所有子节点和他的父亲节点,问要使得所有的节点被覆盖的最少灯塔数量。
考虑每一个节点要被覆盖应该如何放置灯塔。
如果一个节点被覆盖 1 该节点放了灯塔 2 该点的父亲节点放了灯塔 3 该点的儿子节点放了灯塔。
dp[u][0] 表示这个节点的儿子节点放了灯塔
dp[u][1] 表示这个点本身放了灯塔
dp[u][2] 表示这个点的父亲节点放了灯塔
转移方程,
dp[u][1] 可以从儿子的三个状态转移 dp[u][1]=min(dp[v][0],dp[v][1],dp[v][2])
dp[u][2] 那么如果要儿子节点被覆盖,要么儿子本身有灯塔,要么儿子的儿子有灯塔 dp[u][2]=min(dp[v][0],dp[v][1])
dp[u][0] 这个是这个节点的儿子节点放了灯塔,但是如果这个节点有很多个儿子,我们只要其中一个即可
所以这个转移比较复杂,可以像之前的 E. Paint the Tree 树形dp 这个一样的去处理。
不过这个对于子节点选dp[v][1]的限制是只要一个即可,所以可以用一个更简单的方法。
设置一个变量dif,dif=min(dp[v][1]-dp[v][0],dif)
最后在加上这个dif即可,其实两个本质上是一样的。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <bitset>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=3e5+;
typedef long long ll;
vector<int>G[maxn];
void add(int u,int v){
G[u].push_back(v);
G[v].push_back(u);
}
int n;
void read(){
scanf("%d",&n);
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
}
int dp[maxn][];
void dfs(int u,int pre){
dp[u][]=;
dp[u][]=;
dp[u][]=;
for(int i=;i<G[u].size();i++){
int v=G[u][i];
if(v==pre) continue;
dfs(v,u);
dp[u][]+=min(dp[v][],min(dp[v][],dp[v][]));
dp[u][]+=min(dp[v][],dp[v][]);
dp[u][]+=dp[v][];
}
vector<int>val;val.clear();
for(int i=;i<G[u].size();i++){
int v=G[u][i];
if(v==pre) continue;
val.push_back(dp[v][]-dp[v][]);
}
if(val.size()==) dp[u][]=inf;
sort(val.begin(),val.end());
if(val.size()&&val[]>) dp[u][]+=val[];
else {
for(int i=;i<val.size();i++){
if(val[i]>) break;
dp[u][]+=val[i];
}
}
// printf("dp[%d][0]=%d dp[%d][1]=%d dp[%d][2]=%d\n",u,dp[u][0],u,dp[u][1],u,dp[u][2]);
} int main(){
read();
dfs(,-);
printf("%d\n",min(dp[][],dp[][]));
return ;
}
题目差不多。
题目大意:
给你一棵树,要求这棵树的根节点1 到 每一个点的距离要小于等于2 增加的最少的路数。
仔细比划比划 就发现和上面是一样的题目。
只是要标记一下本来就和根节点1 距离小于等于2的所有节点,这些节点的转移有一点不一样,其他都是一样的。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <bitset>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=2e5+;
typedef long long ll;
vector<int>G[maxn];
int vis[maxn];
void add(int u,int v){
G[u].push_back(v);
G[v].push_back(u);
}
int n;
void read(){
scanf("%d",&n);
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
}
int dp[maxn][];
void dfs(int u,int pre){
dp[u][]=;
dp[u][]=;
dp[u][]=;
int dif=inf;
for(int i=;i<G[u].size();i++){
int v=G[u][i];
if(v==pre) continue;
dfs(v,u);
if(vis[u]){
dp[u][]+=min(dp[v][],dp[v][]);
dp[u][]+=min(dp[v][],min(dp[v][],dp[v][]));
dp[u][]+=min(dp[v][],dp[v][]);
}
else{
dp[u][]+=min(dp[v][],min(dp[v][],dp[v][]));
dp[u][]+=min(dp[v][],dp[v][]);
dp[u][]+=min(dp[v][],dp[v][]);
dif=min(dp[v][]-min(dp[v][],dp[v][]),dif);
}
}
if(vis[u]) return ;
dp[u][]+=dif;
} void init(int u,int pre){
vis[u]=;
for(int i=;i<G[u].size();i++){
int v=G[u][i];
vis[v]=;
for(int j=;j<G[v].size();j++){
int x=G[v][j];
vis[x]=;
}
}
} int main(){
read();
init(,-);
dfs(,-);
printf("%d\n",min(dp[][],dp[][]));
return ;
}
树的最小支配集 E - Cell Phone Network POJ - 3659 E. Tree with Small Distances的更多相关文章
- POJ 3659 Cell Phone Network(树的最小支配集)(贪心)
Cell Phone Network Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6781 Accepted: 242 ...
- 树形dp compare E - Cell Phone Network POJ - 3659 B - Strategic game POJ - 1463
B - Strategic game POJ - 1463 题目大意:给你一棵树,让你放最少的东西来覆盖所有的边 这个题目之前写过,就是一个简单的树形dp的板题,因为这个每一个节点都需要挺好处 ...
- 树形DP求树的最小支配集,最小点覆盖,最大独立集
一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合时此点还需要被覆盖,被覆盖也有两种状态,即被子节点覆盖或者被父节点覆盖.总结起来就是三种状态,现对 ...
- 树形DP 树的最小支配集,最小点覆盖与最大独立集
最小支配集: 从V中选取尽量少的点组成一个集合,让V中剩余的点都与取出来的点有边相连. (点) 最小点覆盖: 从V中选取尽量少的点组成一个集合V1,让所有边(u,v)中要么u属于V1,要么v属于V1 ...
- POJ 3398 Perfect Service(树型动态规划,最小支配集)
POJ 3398 Perfect Service(树型动态规划,最小支配集) Description A network is composed of N computers connected by ...
- 树的问题小结(最小生成树、次小生成树、最小树形图、LCA、最小支配集、最小点覆盖、最大独立集)
树的定义:连通无回路的无向图是一棵树. 有关树的问题: 1.最小生成树. 2.次小生成树. 3.有向图的最小树形图. 4.LCA(树上两点的最近公共祖先). 5.树的最小支配集.最小点覆盖.最大独立集 ...
- 求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp
目录 求树的最大独立集,最小点覆盖,最小支配集 三个定义 贪心解法 树形DP解法 (有任何问题欢迎留言或私聊&&欢迎交流讨论哦 求树的最大独立集,最小点覆盖,最小支配集 三个定义 最大 ...
- POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法
POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
随机推荐
- Linux c++ vim环境搭建系列(6)——CMakeLists.txt多文档多目录组织方法和编写示例
CMakeLists.txt学习 1. 概要 主要是关于cmakelists.txt的编写模板,和多文档多目录的组织方法详解, 涉及第三方库的添加使用方法. 这里主要介绍cmakelists.txt的 ...
- 如何配置多个Spring的xml配置文件(多模块配置)
如何使用多个Spring的xml配置文件(多模块配置) (2009-08-22 13:42:43) 如何使用多个Spring的xml配置文件(多模块配置) 在用Struts Spring Hibe ...
- 数组的增加与删除(push、pop、unshift、shift)
1. 数组增删和换位置(原数组将被修改) push() //在数组最后面插入项,返回数组的长度 数组1改后的长度 = 数组1.push(元素1); pop() //取出数组中的最后一 ...
- Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(九)之Interfaces
Interfaces and abstract classes provide more structured way to separate interface from implementatio ...
- php.ini中文详解
[PHP] ;;;;;;;;;;;;;;;;;;;;;;; ; 关于 php.ini 配置文件 ; ;;;;;;;;;;;;;;;;;;;;;;; ; PHP 的初始化文件, 必须命名为 php.in ...
- L21 Momentum RMSProp等优化方法
airfoil4755 下载 链接:https://pan.baidu.com/s/1YEtNjJ0_G9eeH6A6vHXhnA 提取码:dwjq 11.6 Momentum 在 Section 1 ...
- vue中的ref属性
1.什么是ref? ref是用于快速定位到dom结构,vue中一般不去操作dom结构,他是数据驱动的.jQuery会疯狂操作DOM {{msg}} mounted(){ let h = this.$r ...
- radio取值
假设代码如下: 1) <input type="radio" name="radio" id="radio1" checke ...
- IDEA惊天bug:进程已结束,退出代码-1073741819 (0xC0000005)
由于昨天要写的文章没有写完,于是今天早上我四点半就"自然醒"了,心里面有事,睡觉也不安稳.洗漱完毕后,我打开电脑,正襟危坐,摆出一副要干架的态势,不能再拖了. 要写的文章中涉及到一 ...
- ansible playbook loop 翻译
ansible源文档地址 有时候你想多次重复一个任务. 在计算机编程中,这叫做循环. 常见的 Ansible 循环包括使用文件模块更改几个文件和 / 或目录的所有权,使用用户模块创建多个用户,并重复一 ...