0x54 树形DP
树形DP我只知道千万别写森林转二叉树慢的要死
没有上司的舞会 水!裸!
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
} int f[][],h[];
void treedp(int x)
{
f[x][]=;f[x][]=h[x];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
treedp(y);
f[x][]+=max(f[y][],f[y][]);
f[x][]+=f[y][];
}
} int fa[];
int main()
{
int n,x,y;
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&h[i]);
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
ins(y,x);fa[x]=y;
} int rt;
for(int i=;i<=n;i++)
if(fa[i]==)rt=i;
treedp(rt);
printf("%d\n",max(f[rt][],f[rt][]));
return ;
}
没有上司的舞会
选课 带个背包咯,注意一下背包别重复用一个子节点就好
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,next;
}a[];int len,last[];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
} int f[][],h[],tot[];
void treedp(int x)
{
f[x][]=h[x];tot[x]=;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
treedp(y);
for(int i=tot[x];i>=;i--)
for(int j=tot[y];j>=;j--)
f[x][i+j]=max(f[x][i+j],f[x][i]+f[y][j]);
tot[x]+=tot[y];
}
} int fa[];
int main()
{
int n,m,x,y;
scanf("%d%d",&n,&m);
h[]=;
for(int i=;i<=n;i++)
{
scanf("%d%d",&fa[i],&h[i]);
ins(fa[i],i);
}
memset(f,-,sizeof(f));
treedp();
printf("%d\n",f[][m+]);
return ;
}
选课
poj3585 这题还挺有意思哈,书上说这是“不定根”的树形DP问题,有个很高大上的名词叫二次扫描与换根法
其实自己YY一下,设1为根,第一次dfs把每个点管辖的子树的流量d算出来,对于一个点其实它的流量就是这个d值+从父节点流出去的流量,画个图还是很好解决的,就是min(到父节点的边权,父节点的d值-当前点给父节点的贡献)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; struct node
{
int x,y,c,next;
}a[];int len,last[];
void ins(int x,int y,int c)
{
len++;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len;
} bool checkleaf(int x,int fr)
{
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=fr)return false;
}
return true;
} int d[];
void dfs(int x,int fr)
{
d[x]=;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=fr)
{
dfs(y,x);
if(checkleaf(y,x)==true)d[x]+=a[k].c;
else d[x]+=min(a[k].c,d[y]);
}
}
}
int mmax;
void solve(int x,int fr,int rd)
{
mmax=max(mmax,d[x]+rd);
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=fr)
{
int g;
if(checkleaf(y,x)==true)g=d[x]-a[k].c;
else g=d[x]-min(a[k].c,d[y]); if(checkleaf(x,y)==true)solve(y,x,a[k].c);
else solve(y,x,min(rd+g,a[k].c));
}
}
} int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
int n,x,y,c;
scanf("%d",&n);
len=;memset(last,,sizeof(last));
for(int i=;i<n;i++)
{
scanf("%d%d%d",&x,&y,&c);
ins(x,y,c);ins(y,x,c);
}
dfs(,);
mmax=;solve(,,);
printf("%d\n",mmax);
}
return ;
}
poj3585
0x54 树形DP的更多相关文章
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- POJ2342 树形dp
原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...
- hdu1561 The more, The Better (树形dp+背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...
- bzoj2500: 幸福的道路(树形dp+单调队列)
好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...
随机推荐
- Windows 环境下 Docker 使用及配置
原文引用: https://www.cnblogs.com/moashen/p/8067612.html 我们可以使用以下两种方式在Windows环境下使用docker: 1. 直接安装: Docke ...
- SQL Server中char与varchar数据类型区别
在SQL Server中char类型的长度是不可变的,而varchar的长度是可变的 . 存入数据时: 如果数据类型为char时,当定义一个字段固定长度时,如果存进去数据长度小于char的长度,那么存 ...
- Asp.net MVC4 Step By Step(5)-使用Web API
Web API是ASP.net MVC4新增的一个特色, 应用于处理Ajax请求, 他同时使用了Web标准规范, 比如Http, Json,和XML,以及一系列构建REST数据服务的参考原则, 和AS ...
- for 循环练习题(2)
一张纸的厚度是0.0001米,将纸对折,对折多少次厚度超过珠峰高度8848米 var x=0.0001; for(var a=1;true;a++){ x=x*2; if (x>8848) { ...
- 【Oracle】详解10053事件
借助Oracle的10053事件event,我们可以监控到CBO对SQL进行成本计算和路径选择的过程和方法. 10053事件有两个级别: Level 2:2级是1级的一个子集,它包含以下内容: Col ...
- C#让电脑发声,播放声音
//1. [DllImport("Kernel32.dll")] //引入命名空间 using System.Runtime.InteropServices; public sta ...
- DNN:windows使用 YOLO V1,V2
本文有修改,如有疑问,请移步原文. 原文链接: YOLO v1之总结篇(linux+windows) 此外: YOLO-V2总结篇 Yolo9000的改进还是非常大的 由于原版的官方YOLOv ...
- css基础四
过渡属性 下面的表格列出了所有的转换属性: 属性 描述 CSS transition 简写属性,用于在一个属性中设置四个过渡属性. 3 transition-property 规定应用过渡的 CSS ...
- [Advanced Algorithm] - Symmetric Difference
题目 创建一个函数,接受两个或多个数组,返回所给数组的 对等差分(symmetric difference) (△ or ⊕)数组. 给出两个集合 (如集合 A = {1, 2, 3}和集合 B = ...
- Combobox 下拉框赋值
string sql = "select distinct RoleName from tb_Role"; DataTable dt = SqlHelper.DataTable(s ...