暑假集训 || 树DP
树上DP通常用到dfs https://www.cnblogs.com/mhpp/p/6628548.html
POJ 2342
相邻两点不能同时被选 经典题
f[0][u]表示不选u的情况数,此时v可选可不选
f[1][u]表示选u的情况数,此时v不选
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int SZ = ;
const int INF = 1e9+;
int f[][SZ];
int head[SZ], nxt[SZ], l[SZ], tot = ;
void build(int f, int t)
{
l[++tot] = t;
nxt[tot] = head[f];
head[f] = tot;
}
void dfs(int u, int fa)
{
for(int i = head[u];i;i = nxt[i])
{
int v = l[i];
if(v == fa) continue;
dfs(v, u);
f[][u] += max(f[][v], f[][v]);
f[][u] += f[][v];
}
return;
}
int main()
{
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d", &f[][i]);
while()
{
int u, v;
scanf("%d %d", &u, &v);
if(u == && v == ) break;
build(u, v);
build(v, u);
}
dfs(, );
printf("%d\n", max(f[][], f[][]));
return ;
}
URAL 1018
一个二叉树,每条边上都有一定的苹果,减去一些边使得剩下的苹果最多(要从叶子那儿开始剪
f[p][u]表示在u点及它的子树内一共选择p个点,能剩下的最多苹果数
边权不好处理,把它转移到点上
转移时考虑u点(根节点)一定选,在左儿子和右儿子中一共选p-1个,分别枚举即可
记忆化搜索,每次dfs时若这个f[p][u]之前已经算过,可以直接return这个值
struct Tree
{
int lc, rc;
}tree[SZ];
queue<int> q;
int vis[SZ], hasc[SZ];
void bfs()
{
q.push();
vis[] = ;
while(q.size())
{
int u = q.front(); q.pop();
int flag = ;
for(int i = head[u];i;i = nxt[i])
{
int v = l[i].t;
hasc[u] = ;
if(!vis[v])
{
vis[v] = ;
a[v] = l[i].d;
q.push(v);
if(!flag) tree[u].lc = v;
if(flag) tree[u].rc = v;
flag++;
}
}
}
return;
} int dfs(int u, int p)//以u为根的子树,保留p个点
{
if(p == ) return ;
if(f[p][u] > ) return f[p][u];
if(!hasc[u]) return a[u];
for(int i = ; i < p; i++)
{
f[p][u] = max(f[p][u], dfs(tree[u].lc, i) + dfs(tree[u].rc, p-i-) + a[u]);
}
return f[p][u];
}
int main()
{
scanf("%d %d", &n, &Q);
for(int i = ; i < n-; i++)
{
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
build(u, v, w);
build(v, u, w);
}
bfs();
printf("%d\n", dfs(, Q+));
return ;
}
最小支配集 && 最小点覆盖 && 最大独立集
https://www.cnblogs.com/Ash-ly/p/5783877.html
UVA 1218
选一些点,当一个点被选择的时候,它邻接的点就被覆盖了,要求每个点被覆盖有且仅有一次,问最少选多少个点
最小支配集
https://blog.csdn.net/wyjwyl/article/details/51447427
神奇。。。
const int SZ = ;
const int INF = 1e9+;
int f[][SZ];
int head[SZ], nxt[SZ], l[SZ], tot = ;
void build(int f, int t)
{
l[++tot] = t;
nxt[tot] = head[f];
head[f] = tot;
}
/*
f[0][u] u选了
f[1][u] u不选,有一个v选了
f[2][u] u不选,v不选
*/
void dfs(int u, int fa)
{
int sum = , inc = INF;
bool flag = false;
for(int i = head[u]; i; i = nxt[i])
{
int v = l[i];
if(v == fa) continue;
dfs(v, u);
f[][u] += (min(f[][v], f[][v]));
if(f[][v] <= f[][v])
{
sum += f[][v];
flag = true;
}
else
{
sum += f[][v];
inc = min(inc, f[][v] - f[][v]);
}
if(f[][v] != INF && f[][u] != INF) f[][u] += f[][v];
else f[][u] = INF;//
}
if(inc == INF && !flag) f[][u] = INF;
else
{
f[][u] = sum;
if(!flag) f[][u] += inc;
}
return;
}
int main()
{
int n;
while()
{
scanf("%d", &n);
memset(f, , sizeof(f));
memset(head, , sizeof(head));
tot = ;
for(int i = ; i < n-; i++)
{
int u, v;
scanf("%d %d", &u, &v);
build(u, v);
build(v, u);
}
for(int i = ; i <= n; i++) f[][i] = , f[][i] = ;
dfs(, );
printf("%d\n", min(f[][], f[][]));
int tmp;
scanf("%d", &tmp);
if(tmp == -) break;
}
return ;
}
Codeforces 274B
题意:给一棵树,每个点都有权值,每次操作可以把含有1号点的子树所有点权+1或者-1,问最少操作多少次可以让所有点权值都为0
思路:把点1作为根,考虑树上DP,从叶子开始每个点都有sub或者add,表示在这个点要加或减多少
在每个点加减后会影响它的父亲节点,对父亲节点的影响可以取max(要求总的操作次数最少)
神奇的dfs嗯
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
const int SZ = ;
LL v[SZ];
int head[SZ*], nxt[SZ*], l[SZ*], tot = ;
LL sub[SZ], add[SZ];
void build(int f, int t)
{
l[++tot] = t;
nxt[tot] = head[f];
head[f] = tot;
}
void dfs(int u, int fa)
{
for(int i = head[u];i;i = nxt[i])
{
int v = l[i];
if(v != fa)
{
dfs(v, u);
sub[u] = max(sub[u], sub[v]);
add[u] = max(add[u], add[v]);
}
}
v[u] = v[u] - sub[u] + add[u];
if(v[u] > ) sub[u] += v[u];
else add[u] -= v[u];
}
int main()
{
int n;
scanf("%d", &n);
for(int i = ; i < n-; i++)
{
int x, y;
scanf("%d %d", &x, &y);
build(x, y);
build(y, x);
}
for(int i = ; i <= n; i++)
scanf("%I64d", &v[i]);
dfs(, );
printf("%I64d\n", add[] + sub[]);
return ;
}
暑假集训 || 树DP的更多相关文章
- 暑假集训 || 区间DP
区间DP 经典石子合并问题V1 复杂度 On3 int a[SZ], sum[SZ], f[SZ][SZ]; int main() { int n; scanf("%d", ...
- [暑假集训--数位dp]LightOj1205 Palindromic Numbers
A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the sam ...
- [暑假集训--数位dp]hdu3709 Balanced Number
A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. ...
- [暑假集训--数位dp]hdu3555 Bomb
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the ti ...
- [暑假集训--数位dp]hdu3652 B-number
A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- ...
- [暑假集训--数位dp]hdu2089 不要62
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍, ...
- 暑假集训 || 概率DP
Codeforces 148D 考虑状态转移..https://www.cnblogs.com/kuangbin/archive/2012/10/04/2711184.html题意:原来袋子里有w只白 ...
- 2018.8.17 2018暑假集训 关于dp的一些感想(以目前的知识水平)
学了这么长时间的dp似乎还是不怎么样 谨以此篇文字记录一年以来与dp斗智斗勇的各种经历 关于dp(也就是动态规划)似乎对于每个OIer来说都是一个永远的噩梦. 刚刚开始学dp的时候完全搞不明白(只是觉 ...
- [暑假集训--数位dp]hdu5787 K-wolf Number
Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation o ...
随机推荐
- Naïve Bayes Models
贝叶斯模型假设: 为防止概率为零的情况,做拉普拉斯平滑得: 下面介绍一下朴素贝叶斯模型与多变量伯努利模型的区别: 朴素贝叶斯: 多变量伯努利: 即: 多变量伯努利模型不考虑样本出现的次数,每个特征的取 ...
- File System Programming --- (二)
File System Basics The file systems in OS X and iOS handle the persistent storage of data files, app ...
- Eclipse中,Open Type(Ctrl+Shift+T)失效后做法。
好几天ctrl shift T都不好用了,一直认为是工程的问题,没太在意,反正ctrl shift R也可也,今天看同事的好用,于是到网上查了一下解决的方法,刚才试了一下,应该是这个问题,明天就去公司 ...
- 878. Nth Magical Number
A positive integer is magical if it is divisible by either A or B. Return the N-th magical number. ...
- LIS LCS LCIS (主要过一遍,重在做题)
只详细讲解LCS和LCIS,别的不讲-做题优先. 菜鸟能力有限写不了题解,可以留评论,我给你找博客. 先得理解最长上升子序列吧,那个HDOJ拦截导弹系列可以做一下,然后用o(n)log(n)的在做一遍 ...
- 【EXCEL终极总结分享】基于NPOI扩展封装的简易操作工具类库(简单灵活易用,支持导出、导入、上传等常见操作)
对于EXCEL的导入.导出,我之前已分享过多次,比如: 第一种方案:<我写的一个ExcelHelper通用类,可用于读取或生成数据>这个主要是利用把EXCEL当成一个DB来进行获取数据,导 ...
- mac的日常使用总结
目录 有一个github的仓库:(强烈推荐) 不推荐的但是可以试试的一些链接: # 关于mac book的使用教程 github简直是一个宝藏,发现好多各种好玩的东西, 爱了爱了, 开源一定是未来, ...
- Spring 中的 18 个注解,你会几个?
阅读本文大概需要 4 分钟. 作者:Java的小本家 @Controller 标识一个该类是 Spring MVC controller 处理器,用来创建处理 http 请求的对象. @RestCon ...
- RobotFrameWork自动化系列:安装配置
1. RobotFrameWork安装配置 1.1. 安装环境 64位win10家庭中文版 网上很多这方面的教程,但是比较零散,这里是自己安装配置的一个简单的笔记. 1.2. 安装说明 由于Rob ...
- docker系列(一):docker基础与安装笔记
1 什么是docker docker是基于GO语言编写的开源容器项目,诞生于2013年初,到目前为止,已经经历了6年的发展演变.现如今,docker已经非常火爆,特别是在一线IT企业,部署.运维等工作 ...