E - Cell Phone Network

POJ - 3659

题目大意:

给你一棵树,放置灯塔,每一个节点可以覆盖的范围是这个节点的所有子节点和他的父亲节点,问要使得所有的节点被覆盖的最少灯塔数量。

考虑每一个节点要被覆盖应该如何放置灯塔。

如果一个节点被覆盖 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 ;
}

E. Tree with Small Distances

题目差不多。

题目大意:

给你一棵树,要求这棵树的根节点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的更多相关文章

  1. POJ 3659 Cell Phone Network(树的最小支配集)(贪心)

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6781   Accepted: 242 ...

  2. 树形dp compare E - Cell Phone Network POJ - 3659 B - Strategic game POJ - 1463

    B - Strategic game POJ - 1463   题目大意:给你一棵树,让你放最少的东西来覆盖所有的边   这个题目之前写过,就是一个简单的树形dp的板题,因为这个每一个节点都需要挺好处 ...

  3. 树形DP求树的最小支配集,最小点覆盖,最大独立集

    一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合时此点还需要被覆盖,被覆盖也有两种状态,即被子节点覆盖或者被父节点覆盖.总结起来就是三种状态,现对 ...

  4. 树形DP 树的最小支配集,最小点覆盖与最大独立集

    最小支配集: 从V中选取尽量少的点组成一个集合,让V中剩余的点都与取出来的点有边相连. (点) 最小点覆盖: 从V中选取尽量少的点组成一个集合V1,让所有边(u,v)中要么u属于V1,要么v属于V1 ...

  5. POJ 3398 Perfect Service(树型动态规划,最小支配集)

    POJ 3398 Perfect Service(树型动态规划,最小支配集) Description A network is composed of N computers connected by ...

  6. 树的问题小结(最小生成树、次小生成树、最小树形图、LCA、最小支配集、最小点覆盖、最大独立集)

    树的定义:连通无回路的无向图是一棵树. 有关树的问题: 1.最小生成树. 2.次小生成树. 3.有向图的最小树形图. 4.LCA(树上两点的最近公共祖先). 5.树的最小支配集.最小点覆盖.最大独立集 ...

  7. 求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp

    目录 求树的最大独立集,最小点覆盖,最小支配集 三个定义 贪心解法 树形DP解法 (有任何问题欢迎留言或私聊&&欢迎交流讨论哦 求树的最大独立集,最小点覆盖,最小支配集 三个定义 最大 ...

  8. POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法

    POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...

  9. POJ3659 Cell Phone Network(树上最小支配集:树型DP)

    题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...

随机推荐

  1. IntelliJ IDEA 在方法大括号中{}点击回车多出一个},如何取消

    在 File - settings - Editor - General- Smart Keys - Enter 去掉 Insert pair '}' 的对勾就可以了

  2. Jmeter命令行执行并生成HTML报告

    前提:准备好jmeter脚本,找到jmeter配置文件查看生成的日志格式是否为csv,如果不是请改为csv 注意:使用命令执行jmeter脚本必须使用jmeter 3.0及以上版本1.使用命令行执行脚 ...

  3. 如何批量修改文件后缀名,python来帮你

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http ...

  4. First Training

    B B - Local Extrema CodeForces - 888A You are given an array a. Some element of this array ai is a l ...

  5. Python实现按键精灵(一)-键鼠操作

    需要安装 pywin32库 pip install pywin32 import win32api import time #鼠标移动 def mouse_move(x,y): win32api.Se ...

  6. sws_接口自动化_demo

    登录接口获取token: import requests import json def get_token(username, password): host = "https://sws ...

  7. Goldeneye 靶机过关记录

    注:因记录时间不同,记录中1.111和1.105均为靶机地址. 1信息收集 1.1得到目标,相关界面如下: 1.2简单信息收集 wappalyzer插件显示: web服务器:Apache 2.4.7 ...

  8. [数据库]Mysql蠕虫复制增加数据

    将查询出来的数据插入到指定表中,例: 将查询user表数据添加到user表中,数据会成倍增加 insert into user(uname,pwd) select uname,pwd from use ...

  9. redis: List列表类型(四)

    list设置值(头部):lpush list one list设置值(尾部):**rpush ** list one list获取值:lrange list 0 -1 list获取指定范围的值:lra ...

  10. MySQL笔记总结-DDL语言

    DDL语言 数据类型 一.数值型 1.整型 tinyint.smallint.mediumint.int/integer.bigint 1 2 3 4 8 特点: ①都可以设置无符号和有符号,默认有符 ...