HDU 5758 Explorer Bo(树形DP)
【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5758
【题目大意】
给出一棵树,每条路长度为1,允许从一个节点传送到任意一个节点,现在要求在传送次数尽量少的情况下至少经过每条路一遍啊,同时最小化走过的路程总长度。输出路程总长度。
【题解】
首先,对于传送次数尽量少这个条件,我们很容易发现,当且仅当每次出发点和终止点都是叶节点的时候,是最少的,当然在叶节点无法两两匹配的时候,再多走一条链。
然后就是叶节点的匹配问题,使得匹配后的叶节点连线覆盖全图的路径并且经过的总长度最短,这时候考虑考虑每条边对答案的贡献情况,由于匹配方案不唯一,因此每条边的贡献是利用dp使得耗费最小化的。
考虑到边每条边最多经过两次,至少经过一次,那么我们枚举这条边两边的情况,在这个点匹配完一些叶节点后还剩下一些链是没有被匹配的时候所能够做到的最小花费。dp[x][i][j]表示,x节点,在当前的遍历情况下,有i个叶节点没有匹配,j条单独链作为最后多走的一条链的最小花费,显然i最多不超过2,j最多不超过1。那么做一个树形DP,将各种情况从子节点转移到根节点即可,由于考虑到图形的特殊性,一开始树的遍历起点不能是叶节点,才能保证每种情况的遍历。
【代码】
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=200005;
int T,n,k,s[5][2],x,y,dp[N][5][2];
long long ans;
vector<int> g[N];
void dfs(int x,int pre){
if(g[x].size()==1)dp[x][0][1]=dp[x][1][0]=0;
else dp[x][0][0]=0;
for(int i=0;i<g[x].size();i++){
int p=g[x][i];
if(p==pre)continue;
dfs(p,x);
memset(s,60,sizeof(s));
for(int j=2;j>=0;j--)for(int k=2;k;k--)
for(int U=0;U<=min(j,k);U++){
int t=j+k-2*U;
s[t][0]=min(s[t][0],dp[x][j][0]+dp[p][k][0]+k);
s[t][1]=min(s[t][1],dp[x][j][0]+dp[p][k][1]+k);
s[t][1]=min(s[t][1],dp[x][j][1]+dp[p][k][0]+k);
}memcpy(dp[x],s,sizeof(dp[x]));
}for(int i=2;i;i--)dp[x][i-1][1]=min(dp[x][i-1][1],dp[x][i][0]);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)g[i].clear();
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
g[x].push_back(y);g[y].push_back(x);
}if(n<=2)printf("%d\n",n-1);
else{
memset(dp,60,sizeof(dp));
for(int i=1;i<=n;i++)if(g[i].size()>1){
dfs(i,-1);
printf("%d\n",min(dp[i][0][0],dp[i][0][1]));
break;
}
}
}return 0;
}
HDU 5758 Explorer Bo(树形DP)的更多相关文章
- HDU 5758 Explorer Bo
思维,树形$dp$. 首先选择一个度不为$0$的节点作为根节点,将树无根转有根. 这题的突破口就是要求瞬间移动的次数最少. 次数最少,必然是一个叶子节点走到另一个叶子节点,然后瞬间移动一次,再从一个叶 ...
- HDU5758 Explorer Bo 树形dp
我是参考这一篇写的:http://blog.csdn.net/fsss_7/article/details/52049474 一点感想:dp[i][0]代表以这个点为根的且总叶子数为偶数个叶子的答案 ...
- POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题
一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...
- hdu 5452 Minimum Cut 树形dp
Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=54 ...
- HDU 1520 Anniversary party [树形DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题目大意:给出n个带权点,他们的关系可以构成一棵树,问从中选出若干个不相邻的点可能得到的最大值为 ...
- hdu 1520Anniversary party(简单树形dp)
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- Install Air Conditioning HDU - 4756(最小生成树+树形dp)
Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...
- HDU 3586 二分答案+树形DP判定
HDU 3586 『Link』HDU 3586 『Type』二分答案+树形DP判定 ✡Problem: 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏 ...
- HDU 3586.Information Disturbing 树形dp 叶子和根不联通的最小代价
Information Disturbing Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/ ...
随机推荐
- HTTP POST和GET的区别[转]
http://www.cppblog.com/woaidongmao/archive/2008/05/29/51476.aspx 1.HTTP 只有POST和GET 两种命令模式: 2.POST是被设 ...
- 通过OCI 处理 Oracle 10g 中处理Clob大字段写入
Oracle数据库中, 通过存储过程写入Clob字段 , 当数据大于4k时, 报错 ORA-01460: 转换请求无法实施或不合理 经过排查, 数据Bind方式不对, 不能采用字符串的Bind方式 原 ...
- js获取当前url参数的两方式
方法一:正则分析法function getQueryString(name) { var reg = new RegExp("(^|&)" + name + &quo ...
- 1001. 害死人不偿命的(3n+1)猜想
/* * Main.c * 1001. 害死人不偿命的(3n+1)猜想 * Created on: 2014年8月27日 * Author: Boomkeeper *********测试通过***** ...
- SQL Server 权限的分类
SQL Server 的权限可以分三类 第一类 server 层面上的: select * from sys.fn_builtin_permissions(default) where class_d ...
- 深入解析SSD中MLC与SLC的性能差异
固态硬盘(Solid State Disk或Solid State Drive),也称作电子硬盘或者固态电子盘,是由控制单元和固态存储单元(DRAM或FLASH芯片)组成的硬盘. 固态硬盘的接口规范和 ...
- chromedriver bug
https://github.com/FuckTheWorld/chromedriver/issues/1145 https://bugs.chromium.org/p/chromedriver/is ...
- RAID详细介绍
RAID详细介绍 RAID 0 又称为Stripe或Striping,它代表了所有RAID级别中最高的存储性能.RAID 0提高存储性能的原理是把连续的数据分散到多个磁盘上存取,这样,系统有数据请求就 ...
- Qt编写端口扫描工具
Qt提供了QTcpSocket类,可以方便地建立TCP连接.利用这一功能,Maxiee编写了一个简单地端口扫描工具. 软件的功能就是,扫描某一网段的固定端口,如80端口,若目的地址开放了这一端口,那么 ...
- Oracle中如何判断字符串是否全为数字,以及从任意字符串中提取数字
本文介绍了判断字符串是否全为数字的4种办法,另外还介绍了一个translate函数的小技巧,从任意字符串中提取数字(调用2次translate函数).这个办法是一个公司同事发现的,用起来很方便,但理解 ...