树形dp系列
1.火车站开饭店
最大独立集裸题
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<string>
#define N 200000+20
using namespace std;
];
;
void link(int x,int y){
nxt[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
void dfs(int x,int fa){
dp[x][]=a[x];//0为在独立集里
dp[x][]=;//1为不在
for (int i=head[x];i;i=nxt[i]){
if (to[i]==fa) continue;
dfs(to[i],x);
dp[x][]+=dp[to[i]][];
dp[x][]+=max(dp[to[i]][],dp[to[i]][]);
}
}
int main(){
scanf ("%d",&n);
;i<=n;++i) scanf ("%d",&a[i]);
int x,y;
;i<n;++i){
scanf ("%d%d",&x,&y);
link(x,y),link(y,x);
}
dfs(,);
printf (][],dp[][]));
;
}
2.树的最小染色
考题 当时只打了两个状态 居然用我神奇的调试功力搞了10分?
考完之后愣是想了好久才想通 好像是最小支配集
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define maxn 300000
#define INF 10000100
using namespace std;
,root=,sum,f[maxn][],ans=,g[maxn],sz[maxn];
void link(int x,int y)
{
nxt[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
void dfs(int x)
{
if (!sz[x])//0 靠爸爸 1 靠儿子 2 靠自己
{
f[x][]=,f[x][]=INF>>,f[x][]=v[x];
return ;
}
,fl=;
for (int i=head[x];i;i=nxt[i])
{
int t=to[i];
dfs(t);
f[x][]+=min(f[t][],min(f[t][],f[t][]));
f[x][]+=f[t][];
]>=f[t][]) fl=,s2+=f[t][];
],s1=min(s1,f[t][]-f[t][]);
}
f[x][]+=v[x];
f[x][]=s2;
]+=s1;
}
int main()
{
int n;
scanf ("%d",&n);
;i<=n;++i)
{
int x,y,z,k;
scanf ("%d%d%d",&x,&y,&z);
v[x]=y,sz[x]=z;
;j<=z;++j)
{
scanf ("%d",&k);
link(x,k);
g[k]=;
}
}
;i<=n;++i) if (!g[i]) root=i;
dfs(root);
cout<<min(f[root][],f[root][]);
;
}
3.POJ 3659 Cell Phone Network
最小支配集 模板题 另外我发现我真的很喜欢打靠爸爸靠儿子还是靠自己之类的话23333
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<string>
#define ll long long
#define db double
#define N 20000
#define inf 1000000000
using namespace std;
];
;
void link(int x,int y){
nxt[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
void dfs(int x,int fa){
dp[x][]=,dp[x][]=,dp[x][]=;//0属于 1靠儿子 2靠父亲
,q=inf;
for (int i=head[x];i;i=nxt[i]){
int t=to[i];
if (t==fa) continue;
dfs(t,x);
dp[x][]+=min(dp[t][],min(dp[t][],dp[t][]));
]!=inf&&dp[x][]!=inf) dp[x][]+=dp[t][];
]=inf;
]>=dp[t][]) dp[x][]+=dp[t][],fl=t;
]+=dp[t][];
q=min(q,dp[t][]-dp[t][]);
}
]+=q;
]) dp[x][]=inf;
}
int main(){
int n;
scanf ("%d",&n);
int x,y;
;i<n;++i){
scanf ("%d%d",&x,&y);
link(x,y),link(y,x);
}
dfs(,);
printf (][],dp[][]));
;
}
4.POJ 2152 消防站
神题啊qwq 怎么推的出(瘫
围观了一下dalao的论文感觉很有道理又觉得不是很明白
后来翻到:http://blog.csdn.net/loi_dqs/article/details/50878337 在吸取了论文部分内容的基础上很快就明白了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#define ll long long
#define db double
#define N 5000
using namespace std;
;
int w[N],d[N],k[N],de[N][N],ans[N],f[N][N];
struct hh{
int to,nxt,w;
}b[N];
int head[N];
void link(int x,int y,int w){
b[++tot].nxt=head[x];
b[tot].to=y;
b[tot].w=w;
head[x]=tot;
}
void dis(int x,int y,int fa,int di){
de[x][y]=min(de[x][y],di);
for (int i=head[y];i;i=b[i].nxt){
int v=b[i].to;
if (v==fa) continue;
dis(x,v,y,di+b[i].w);
}
}
void dp(int x,int fa){
for (int i=head[x];i;i=b[i].nxt){
int t=b[i].to;
if (t==fa) continue;
dp(t,x);
}
;i<=n;++i){
if (de[x][i]>d[x]) continue;
f[x][i]=w[i];
for (int j=head[x];j;j=b[j].nxt){
int k=b[j].to;
if (k==fa) continue;
f[x][i]+=min(f[k][i]-w[i],ans[k]);
}
ans[x]=min(ans[x],f[x][i]);
}
}
int main(){
scanf ("%d",&n);
;i<=n;++i) scanf ("%d",&w[i]);
;i<=n;++i) scanf ("%d",&d[i]);
int x,y,z;
;i<n;++i){
scanf ("%d%d%d",&x,&y,&z);
link(x,y,z);link(y,x,z);
}
memset(f,0x3f,sizeof(f));
memset(de,0x3f,sizeof(de));
memset(ans,0x3f,sizeof(ans));
;i<=n;++i) dis(i,i,,);
dp(,);
printf (]);
;
}
UPD 2017_07_12
连考两天树形dp我都在鬼混 感觉很不好意思TAT(之前可能是白学了)(那个白学 不是那个白学)
发现了一点小套路?
感觉这一类题经常可以用两个dp的数组分别搞然后分情况转移合并 这样思路比较简单
也可以设三个左右状态互相转移 实现起来会更清爽qwq
然后好像经常设的都是N×M之类的 一般要数据范围别太大才能玩吧
状态大多跟父节点 子节点 子树的个数 在不在某状态中 一类有关qwq
还需多多领悟啊= =
树形dp系列的更多相关文章
- HDU 4514 湫湫系列故事——设计风景线(并查集+树形DP)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) To ...
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- 树形DP水题系列(1):FAR-FarmCraft [POI2014][luogu P3574]
题目 大意: 边权为1 使遍历树时到每个节点的时间加上点权的最大值最小 求这个最小的最大值 思路: 最优化问题 一眼树形DP 考虑状态设立 先直接以答案为状态 dp[u] 为遍历完以u为根的子树的答案 ...
- 【二叉树-最长路径系列(任意路径)】直径、最长同值路径、 最大路径和(DFS、树形DP)
总述 这类题目都是求一个最长路径,这个路径可以不经过根节点. 使用dfs(即递归地遍历树)的方法.维护一个全局最长路径max作为最终结果,而递归方法dfs返回的是含根节点的最长路径.(若不使用全局变量 ...
- 【BZOJ-1864】三色二叉树 树形DP
1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 659 Solved: 469[Submit][Status] ...
- 代码风格与树形DP
Streaming很惨,不过因为比赛之间没有提交过就没掉(或掉了)rating.第二题是一个树形DP,但是我都在想第一题了,简直作死. 看着神犇的代码我也是醉了...各种宏,真是好好写会死系列. 看到 ...
- 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】
Colorful Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- hdu 4514 并查集+树形dp
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- 树形DP——动态规划与数据结构的结合,在树上做DP
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第15篇,也是动态规划系列的第4篇. 之前的几篇文章当中一直在聊背包问题,不知道大家有没有觉得有些腻味了.虽然经典的文 ...
随机推荐
- JAVA提高十八:Vector&Stack深入分析
前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我们先看一个例子:栈就相当于一个很窄的木桶,我们往木桶里放东西,往外拿东 ...
- ASP.NET Core 一步步搭建个人网站(持续更新中~~~)
摘要 ASP.NET Core2.0发布有一阵子了,这是.NET 开源跨平台的一个重大里程碑, 也意味着比1.0版本要更加成熟.目前.net core具有开源.跨平台.灵活部署.模块化架构等等特性,吸 ...
- 《Android源码设计模式》学习笔记之ImageLoader
微信公众号:CodingAndroid cnblog:http://www.cnblogs.com/angel88/ CSDN:http://blog.csdn.net/xinpengfei521 需 ...
- IPv6 VS IPv4,谈谈升级 IPv6 的必要性
11月26日,中办.国办印发了<推进互联网协议第六版(IPv6)规模部署行动计划>,提出国内要在 5~10 年的时间形成下一代互联网自主技术体系和产业生态,建成全球最大规模的 IPv6 商 ...
- Java第三季
1.异常简介: (1) Java中的所有不正常类都继承于Throwable类.Throwable主要包括两个大类,一个是Error类,另一个是 Exception类: (2)其中Error类中包括虚拟 ...
- MongoDB一:入门(安装与配置)
一.简介 MongoDB 是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. mongoDB MongoDB 是一个介于关系数据库和非关系数据库 ...
- Web Api 2.0中使用Swagger生成Api文档的2个小Tips
当Web Api 2.0使用OAuth2授权时,如何在Swagger中添加Authorization请求头? Swagger说明文档支持手动调用Api, 但是当Api使用OAuth2授权时,由于没有地 ...
- 乘积最大洛谷p1018
题目描述 今年是国际数学联盟确定的“2000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得 ...
- springboot之Jwt验证
简介 什么是JWT(Json Web Token) jwt是为了在网络应用环境间传递声明而执行的一种基于json的开放标准.该token被设计紧凑且安全的,特别适用于SSO场景. jwt的声明一般被用 ...
- OGNL简介
OGNL 一:OGNL简介 OGNL的全称是Object Graph Navigation Language即对象导航语音.它是一个开源项目,工作在视图层,用来取代页面中的java脚本.简化数据 ...