树的最小支配集 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了. ...
随机推荐
- 条件变量 condition_variable wait_for
wait_for(阻塞当前线程,直到条件变量被唤醒,或到指定时限时长后) #include <iostream> #include <atomic> #include < ...
- 聊聊Disruptor 和 Aeron 这两个开源库
Disruptor The best way to understand what the Disruptor is, is to compare it to something well under ...
- kworkerds 挖矿木马简单分析及清理
公司之前的开发和测试环境是在腾讯云上,部分服务器中过一次挖矿木马 kworkerds,本文为我当时分析和清理木马的记录,希望能对大家有所帮助. 现象 top 命令查看,显示 CPU 占用 100%,进 ...
- 一些SpringBoot的初步理解
SpringBoot SpringBoot作为近几年很火的微服务框架,只需要简单的几个依赖,少量的配置,就可以使用它快速搭建一个轻量级的微服务,优点是简单.快速.大道至简,缺点是真的太单一,不适于项目 ...
- 上班无聊,自己用python做个小游戏来打发时间
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取t.cn ...
- Daily Scrum 1/14/2016
Zhaoyang & Yandong: Still optimizing the speech input interface Dong & Fuchen: Image asynchr ...
- DeepinV20系统文件管理器右键发送至为知笔记
1. 创作背景 昨天在深度系统上做了一个打开文件管理器选择文件右键发送文本至博客园的插件. 这个插件对于我自己来说是及其方便的东西,平时的学习积累,工作经验或者生活感悟,随手记下之后,就能够轻松发送出 ...
- 数据结构(C语言版)---二叉树
1.二叉树:任意一个结点的子结点个数最多两个,且子结点的位置不可更改,二叉树的子树有左右之分. 1)分类:(1)一般二叉树(2)满二叉树:在不增加树的层数的前提下,无法再多添加一个结点的二叉树就是满二 ...
- CVE-2018-12613 的一些思考
复现 CVE-2018-12613 的一些思考,关于文件包含路径的问题 漏洞 /index.php 第 55 行 $target_blacklist = array ( 'import.php', ' ...
- C# 基础知识系列- 13 常见类库介绍(二)日期时间类
0. 前言 上一篇内容介绍了Console类和Math类,这篇内容着重介绍一下C#中时间日期的处理方式. 上一篇勘误: 上一篇中关于静态类没有构造函数,这一表述有误.正确的说法是C#中静态类不包含常规 ...