树的最小支配集 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了. ...
随机推荐
- 列表推导式和seed()的理解
Table of Contents generated with DocToc 列表推导式和seed()的理解 对seed()的理解 列表推导式 第一种用法 第二种用法 列表推导式和seed()的理解 ...
- vscode连接云服务,搭建Python远程开发
配置Python远程开发环境前提 配置步骤 1.windows 10 开发机配置 win10 1809后支持ssh ssh-keygen -t rsa -b 4096 #会显示生成到的目录C:\Use ...
- Web 如何搭建自己的个人网站
如何搭建自己的个人技术博客网站 学习目标 1.[了解]搭建网站需要的web构件和网站运行原理 2.[掌握]如何搭建个人博客网站 学习前言 大家都是学习开发的,相信都接触过百度,新浪,淘宝,京东...等 ...
- TcxGrid
一.列的宽度为64时,其宽度会自动根据字段的长度调整,设置其他值即为固定值: 二.cell中显示按钮:选中某列,在properties中更改为ButtonEdit,点击子属性buttons添加butt ...
- BUG 测试计划
性能追求 目前状况 测试标准 APP平稳运行,无crush现象 快速下拉翻页时,崩溃退出 要求多人使用,均流畅无异常退出方可 页面的放大缩小不会造成页面显 ...
- 数据结构之栈—强大的四则复杂运算计算器(超过windows自带的科学计算器)【中缀转后缀表达式】
比windows自带计算器还强的四则复杂运算计算器! 实测随机打出两组复杂算式:-7.5 * 6 / ( -2 + ( -6.5 - -5.22 ) )与7.5+-3*8/(7+2) windows ...
- Linux工程师必备的系统监控工具
WGCLOUD基于java语言开发,是微服务架构构建监控系统,支持高并发高性能高可用,核心模块包括:服务器集群监控,ES集群状态监控,CPU监控,内存监控,数据监控(mysql,postgresql, ...
- python os模块获取指定目录下的文件列表
bath_path = r"I:\ner_results\ner_results" dir_list1 = os.listdir(bath_path) for dir1 in di ...
- MySQL之外键、主键、自增
1.创建外键 create table userinfo( uid int auto_increment primary key, name varchar(32), department_id in ...
- 随笔之——浮动(float)的影响及其清除、、clear与overflow-hidden清除float的不同!!!
一.浮动(float)对内联元素的影响. 1.我们都知道,内联元素(例如:span/img/input...)在正常情况下不可以对其设置宽高的,它的大小之只和它内部内容的多少有关. 我们怎样才可以对其 ...