暑假集训 || 树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 ...
随机推荐
- Get与Post的小知识
Get与Post的小知识 一.传递参数: Get把参数包含在URL中,而在Post通过request body传递参数.因为参数直接暴露在URL上,GET比POST更不安全,所以不能用来传递敏感信息. ...
- UVa 1611 Crane (构造+贪心)
题意:给定一个序列,让你经过不超过9的6次方次操作,变成一个有序的,操作只有在一个连续区间,交换前一半和后一半. 析:这是一个构造题,我们可以对第 i 个位置找 i 在哪,假设 i 在pos 位置, ...
- Android EditText实现小数点后几位的终级方案
有时候,我们用EditText的时候,会要求输入小数点后几位,遇到过几次这样的需求,这次把它给记下来,方便以后使用 /** * 小数位数 */ public class PointLengthFilt ...
- E20180503-hm
in terms of 根据; 用…的话; 就…而言; 以…为单位; in term of 就……而言 argument n. 论据; 争论,争吵; [数] 幅角; 主题,情节; indicate ...
- E20180425-hm
zoom n. 变焦; 嗡嗡声; 隆隆声; (车辆等) 疾驰的声音; deprecate vt. 不赞成,不推荐, 反对;
- curl:出现SSL错误提示
在上一篇博文中,升级ruby版本中,提示如下错误: 1) Error fetching https://mirrors.aliyun.com/rubygems/: [root@web ~]# gem ...
- MYSQL性能调优与架构设计之select count(*)的思考
select count(*)的思考 原文:MYSQL性能调优与架构设计 举例: 这里我们就拿一个看上去很简单的功能来分析一下. 需求:一个论坛帖子总量的统计 附加要求:实时更新 在很多人看来,这 ...
- Jquery | 基础 | 导航条在项目中的应用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- CSS选择器优先级【转】
样式的优先级 多重样式(Multiple Styles):如果外部样式.内部样式和内联样式同时应用于同一个元素,就是使多重样式的情况. 一般情况下,优先级如下: (外部样式)External styl ...
- 洛谷1083(差分+二分 or 线段树)
第一种方法:可以二分最大天数订单的答案然后通过差分求一下是否可行. ; int n, m, a[maxn], ans; struct section { int cnt, l, r; }b[maxn] ...