思路:首先声明我是参考:http://blog.csdn.net/frog1902/article/details/9921845这位大牛的博客的。

他说的已经很详尽,但我还是要补充几点。

看完他的解题报告在看我的才好些。

我这的back[i]对于他的lim[i]。

我要补充的是,back[i]不是真正的back[i],可以看到这行代码:back[u]=max(back[u],dep[v]+1);也就是说是其返回祖节点再往下的一个节点。

对于没有回退边的点,其back[i]==0相当于有一个回退边到根节点,那么本节点到根节点上的任何一条边被选择都是可行的。

dp时,首先将dp[u][i](back[u]<=i<=dep[u])置为0,意义是如果在u到back[u]之间已经有一条边被其他节点选择了,那么其不考虑有子节点的话,需要的边数就是0。dp[u][dep[u]]++的意义是选择dep[u]到其父节点的边的点正是u自己。

我个人认为最难理解的是对于dp[u][j],要从dp[v][dep[v]]与0<=k<=j的深度中选取最小的dp[v][k]求和作为dp[u][j]的值。

由于dp[u][j]的意义是选择了深度为j的节点到其父节点的边后,以u为根的子树仍需要多少边,那么可以这个值也就是选择了深度为j的节点到其父节点的边后,以其子节点为根还需要dp[v][j]已经确定,那么自然以u为根的需要边数就是其子节点需要边数的和(前提是所有的选边一定要合法,合法的就是这条边一定要在back[u]到u的路径上)。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#define Maxn 2010
using namespace std;
int dp[Maxn][Maxn],dep[Maxn],back[Maxn],n,m,vi[Maxn];
vector<int> head[Maxn];
void init()
{
memset(dp,-,sizeof(dp));
memset(dep,,sizeof(dep));
memset(vi,,sizeof(vi));
memset(back,,sizeof(back));
for(int i=;i<=n;i++)
head[i].clear();
}
void add(int u,int v)
{
head[u].push_back(v);
head[v].push_back(u);
}
void dfs(int u)
{
int i,v,sz;
vi[u]=;
sz=head[u].size();
for(i=;i<sz;i++)
{
v=head[u][i];
if(vi[v]) continue;
dep[v]=dep[u]+;
dfs(v);
}
}
void Treedp(int u)
{
int i,v,sz,j;
vi[u]=;
sz=head[u].size();
for(i=back[u];i<=dep[u];i++)
dp[u][i]=;
for(i=;i<sz;i++)
{
v=head[u][i];
if(vi[v]) continue;
Treedp(v);
int temp=dp[v][dep[v]];
for(j=;j<=dep[u];j++)
{
if(dp[v][j]!=-)
{
if(temp!=-)
temp=min(temp,dp[v][j]);
else
temp=dp[v][j];
}
if(j>=back[u])
{
if(temp!=-)
dp[u][j]+=temp;
}
}
}
if(u!=)
dp[u][dep[u]]++;
}
int main()
{
int i,j,u,v;
while(scanf("%d%d",&n,&m)!=EOF,n||m)
{
init();
for(i=;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
dfs();
for(i=n;i<=m;i++)
{
scanf("%d%d",&u,&v);
if(dep[u]<dep[v])
swap(u,v);
back[u]=max(back[u],dep[v]+);
}
memset(vi,,sizeof(vi));
Treedp();
printf("%d\n",dp[][]);
}
return ;
}

hdu 4582 树状DP的更多相关文章

  1. hdu 4679 树状dp

    思路:我们其实只需要枚举每条边,求得最小值就行了. 先dfs算出每个节点作为根时,其子树的最长路径,以及进过该节点的最长,次长,第三长路径. 然后在次dfs枚举求出切断某条边,求出这条边的两个端点为子 ...

  2. hdu 4340 树状DP

    思路:我们定义两个数组,ant[Maxn][2],bob[Maxn][2].ant[i][0]表示还未确定哪个城市被全费用占领,ant[i][1]表示确定了哪个城市被全费用占领.那么ant[i][0] ...

  3. HDU 4035Maze(树状+概率dp,绝对经典)

    题意: 给你n个节点的树,从1节点开始走,到每个节点都有三种情况,被杀死回到1节点,找到隐藏的出口出去,沿着当前节点相邻的边走到下一个节点,给出每个节点三种情况发生的概率分别为ki,ei,1-ki-e ...

  4. hdu 1561 The more, The Better_树状dp

    题目链接 题意:给你一棵树,各个节点都有价值(除根节点),从根节点出发,选择m个节点,问最多的价值是多小. 思路:很明显是树状dp,遍历树时背包最优价值,dp[i][k]=max{dp[i][r]+d ...

  5. HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)

    Description A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...

  6. 树状DP HDU1520 Anniversary party

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:职员之间有上下级关系,每个职员有自己的happy值,越高在派对上就越能炒热气氛.但是必须是 ...

  7. 树状DP (poj 2342)

    题目:Anniversary party 题意:给出N各节点的快乐指数,以及父子关系,求最大快乐指数和(没人职员愿意跟直接上司一起玩): 思路:从底向上的树状DP: 第一种情况:第i个员工不参与,F[ ...

  8. poj3659树状DP

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6273   Accepted: 225 ...

  9. poj 2342 Anniversary party_经典树状dp

    题意:Ural大学有n个职员,1~N编号,他们有从属关系,就是说他们关系就像一棵树,父节点就是子节点的直接上司,每个职员有一个快乐指数,现在要开会,职员和职员的直接上司不能同时开会,问怎才能使开会的快 ...

随机推荐

  1. App Extension编程指南(iOS8/OS X v10.10)中文版

    http://www.cocoachina.com/ios/20141023/10027.html 当iOS 8.0和OS X v10.10发布后,一个全新的概念出现在我们眼前,那就是应用扩展.顾名思 ...

  2. 5个Xcode开发调试技巧

    转自Joywii的博客,原文:Four Tips for Debugging in XCode Like a Bro    1.Enable NSZombie Objects(开启僵尸对象) Enab ...

  3. poj 1469 COURSES(匈牙利算法模板)

    http://poj.org/problem?id=1469 COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:  ...

  4. Activator.CreateInstance 方法 (Type) 的用法

    转自:http://www.cnblogs.com/lmfeng/archive/2012/01/30/2331666.html Activator.CreateInstance 方法 (Type) ...

  5. MVC4学习过程记录

    终于决定开始尝试Web开发,即是为了工作也是为了自己的兴趣,决定还是从MS的MVC4开始. 首先从Asp.Net MVC4入门指南这个系列开始学习(http://www.cnblogs.com/pow ...

  6. VS2012与NUnit

    微软提供的NUnit插件是针对vs2010的,而vs2012会自动识别,测试环境为64位win7,具体操作步骤如下 1.下载安装NUnit(NUnit-2.6.3.msi) 2.新建测试项目UnitT ...

  7. jsp界面动态时间显示

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  8. Java模拟登陆02【转载】

    在使用java访问URL时,如果该URL需要身份验证,那么就不能够直接访问,因为没有登陆.那么,如何解决这个问题呢?     方法是使用java模拟登陆,登陆后记录下cookie信息,在下次发起请求时 ...

  9. C#调用WORD处理的实例代码(包含excel)

    最近程序人生(http://www.manong123.com)一个朋友让我帮他做一个小功能,其实就是把WORD文档里的内容存到数据库里去,可以实现搜索并转EXCEL的功能,需求很简单,想不到加上部署 ...

  10. sed常见使用方法总结

    编辑文本 sed -i '1i xyz' test.txt 在第一行之前 sed -i '1a xyz' test.txt 在第一行之后插入 sed -i '1c xyz' test.txt 把第一行 ...