Problem

给你一棵树,可以在每个点上选择造塔或不造,每座塔可以覆盖这个节点和相邻节点,问覆盖整棵树的最小塔数。

Solution

看到这道题的第一眼,我就觉得是一题贪心题,但看见出题的时候分类在树形DP,于是就没仔细想贪心。

树形DP:f[u][0]表示u被其儿子覆盖,f[u][1]表示u上有塔,f[u][2]表示u被其父亲覆盖,转移显然

贪心:我们dfs到叶子节点时,尽量贪心覆盖它的父亲

Notice

树形DP的状态确实很难想到

Code

树形DP

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define sqz main
#define ll long long
#define reg register int
#define rep(i, a, b) for (reg i = a; i <= b; ++i)
#define per(i, a, b) for (reg i = a; i >= b; --i)
#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)
const int INF = 1e9, N = 10000;
const double eps = 1e-6, phi = acos(-1);
ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}
ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}
void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}
struct node
{
int vet, next;
}edge[2 * N + 5];
int ans = 0, flag[N + 5], num = 0, head[N + 5];
inline void add(const int &u, const int &v)
{
edge[++num].vet = v, edge[num].next = head[u], head[u] = num;
edge[++num].vet = u, edge[num].next = head[v], head[v] = num;
}
inline void dfs(reg u, reg fa)
{
reg tt = 0;
travel(i, u)
{
int v = edge[i].vet;
if (v == fa) continue;
dfs(v, u);
if (flag[v]) tt = 1;
}
if (!tt && !flag[u] && !flag[fa])
{
ans++;
flag[fa] = 1;
}
}
int sqz()
{
reg n = read();
rep(i, 1, n - 1) add(read(), read());
dfs(1, 0);
write(ans); puts("");
return 0;
}

贪心

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define sqz main
#define ll long long
#define reg register int
#define rep(i, a, b) for (reg i = a; i <= b; i++)
#define per(i, a, b) for (reg i = a; i >= b; i--)
#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)
const int INF = 1e8, N = 10000;
const double eps = 1e-6, phi = acos(-1);
ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}
ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}
void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}
int f[N + 5][3], head[N + 5];
int num = 0;
struct node
{
int vet, next;
}edge[2 * N + 5];
void add(int u, int v)
{
edge[++num].vet = v;
edge[num].next = head[u];
head[u] = num;
edge[++num].vet = u;
edge[num].next = head[v];
head[v] = num;
}
void dp(int u, int fa)
{
int sum = 0;
f[u][1] = 1, f[u][0] = INF;
travel(i, u)
{
int v = edge[i].vet;
if (v == fa) continue;
dp(v, u);
f[u][0] = min(f[u][0], f[v][1] - min(f[v][1], f[v][0]));
f[u][1] += min(f[v][0], min(f[v][1], f[v][2]));
f[u][2] += f[v][0];
sum += min(f[v][0], f[v][1]);
}
f[u][0] += sum;
}
int sqz()
{
int n = read();
rep(i, 1, n - 1) add(read(), read());
dp(1, 0);
printf("%d\n", min(f[1][0], f[1][1]));
return 0;
}

[BZOJ1596]电话网络的更多相关文章

  1. DP——由蒟蒻到神犇的进阶之路

    开始更新咯 DP专题[题目来源BZOJ] 一.树形DP 1.bzoj2286消耗战 题解:因为是树形结构,一个点与根节点不联通,删一条边即可, 于是我们就可以简化这棵树,把有用的信息建立一颗虚树,然后 ...

  2. BZOJ1596: [Usaco2008 Jan]电话网络

    1596: [Usaco2008 Jan]电话网络 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 513  Solved: 232[Submit][S ...

  3. BZOJ1596 [Usaco2008 Jan]电话网络 【树形dp】

    题目链接 BZOJ1596 题解 先抽成有根树 设\(f[i][0|1][0|1]\)表示以\(i\)为根,儿子都覆盖了,父亲是否覆盖,父亲是否建塔的最少建塔数 转移一下即可 #include< ...

  4. 【bzoj1596】[Usaco2008 Jan]电话网络

    题目描述 Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来 ...

  5. 【bzoj1596】[Usaco2008 Jan]电话网络 树形dp

    题目描述 Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来 ...

  6. [BZOJ1596] [Usaco2008 Jan]电话网络(树形DP || 贪心)

    传送门 1.树形DP #include <cstdio> #include <cstring> #include <iostream> #define N 1000 ...

  7. 1596: [Usaco2008 Jan]电话网络

    1596: [Usaco2008 Jan]电话网络 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 601  Solved: 265[Submit][S ...

  8. 3336 /P1948电话网络(二分答案)

    3336 电话网络  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold       题目描述 Description 由于地震使得连接汶川县城电话线全部损坏,假如你是 ...

  9. USACO2008 Jan 电话网络

    Time Limit: 10 Sec Memory Limit: 162 MB Description Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶 ...

随机推荐

  1. python操作字符串类型json的注意点

    python操作json的方法有json.dumps——将json对象(字典)转换为字符串对象json.loads——将字符串对象转换为json对象(字典)如果定义json对象jsonstring1= ...

  2. idea提交git报错Push rejected: Push to origin/master was rejected

    参考https://blog.csdn.net/u012934325/article/details/71023241

  3. C++读写图片数据转成Base64格式

    转载:http://www.cnblogs.com/jeray/p/8746976.html 转载:https://www.cnblogs.com/lujin49/p/4957742.html 转载: ...

  4. mysql5.7.21下载及安装步骤

    以前都是用的5.6的数据库,现在想着换个新版本数据库.跟上时代的步伐,于是安装了一天才安装好.具体步骤如下: 1.官网下载mysql解压zip版,由于客户端安装版都是32位的,我的电脑是64位系统,所 ...

  5. linux下编译时遇到fatal error: openssl/sha.h: No such file or directory怎么办?

    答:安装ssl开发库 ubuntu下的安装方法为: sudo apt-get install libssl-dev -y

  6. 记录近期面试题,面试总结 (从css - vue 全面面试题)

    记录近期换工作时遇到的面试题和面试题答案 css 部分 盒模型 问题:说一下 css 的盒模型 盒模型分为标准模型和怪异盒模型(IE 盒模型) 标准盒模型:盒模型的宽高只是内容(content)的宽高 ...

  7. Collectors类中的静态工厂方法

    工厂方法 返回类型 用于 toList List<T> 把流中的所有数据元素收集到List集合中. stream.collect(toList());  toSet Set<T> ...

  8. 从vue源码看props

    前言 平时写vue的时候知道props有很多种用法,今天我们来看看vue内部是怎么处理props中那么多的用法的. vue提供的props的用法 1. 数组形式 props: ['name', 'va ...

  9. 查看linux是ubuntu还是centos

    方式一: radhat或centos存在: /etc/redhat-release 这个文件[ 命令 cat /etc/redhat-release ] ubuntu存在 : /etc/lsb-rel ...

  10. postgresql 空间函数 随笔

    1. ST_Buffer(geometry, double, [integer])buffer操作一个很有用函数,这个函数的第一个参数是要操作的空间几何数据,第二个参数长度(距离),第三个参数为一个整 ...