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. AI illustrator 如何裁剪图片(扣取局部区域)

    AI如何裁剪图片 在使用illustrator的过程中,很多亲想要AI的裁剪功能与ps一样强大,但是AI常用的裁剪图片方法如下. 工具/原料  illustrator cs6 应用剪切蒙版剪切图片   ...

  2. Cent OS & Windows 双系统自定义引导菜单

    系统环境 系统:Windows 10 (64-bit) & Cent OS 7 (64-bit) 引导程序:Grub2 编辑 grub.cfg 为了方便,在终端使用命令 su 输入密码进入超级 ...

  3. oracle数据库查看和解除死锁

    查看死锁: select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_ ...

  4. JS 作用域与变量提升---JS 学习笔记(三)

    你知道下面的JavaScript代码执行时会输出什么吗? var foo = 1; function bar() { if (!foo) { var foo = 10; } console.log(f ...

  5. react项目中实现元素的拖动和缩放实例

    在react项目中实现此功能可借助 react-rnd 库,文档地址:https://github.com/bokuweb/react-rnd#Screenshot .下面是实例运用: import ...

  6. 使用 Chrome DevTools 调试 JavaScript

    参考网址如下: http://www.css88.com/archives/8175 https://jingyan.baidu.com/article/67508eb423d2929ccb1ce45 ...

  7. leecode第五百五十七题(反转字符串中的单词 III)

    class Solution { public: string reverseWords(string s) { string res; stack<char> sta; string:: ...

  8. 论文阅读-attention-is-all-you-need

    1结构介绍 是一个seq2seq的任务模型,将输入的时间序列转化为输出的时间序列. 有encoder和decoder两个模块,分别用于编码和解码,结合时是将编码的最后一个输出 当做 解码的第一个模块的 ...

  9. legend2---开发日志11(如何提高终极开发效率)

    legend2---开发日志11(如何提高终极开发效率) 一.总结 一句话总结: 实在没必要摸索着做,直接学了做,用专门的东西来做,岂不是要省时省事很多.岂不美哉. 1.vue中的滚动字幕动画效果如何 ...

  10. fail to resolve com.umeng.analytics:analytics:latest.integration

    今天友盟接入的时候,他娘的居然提示我这个友盟jar包拉不下来 明明之前还好好的,而且别的什么东西都没问题,就这个有问题 原来使用的是 compile "com.umeng.analytics ...