HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)
Description
A cycle of n nodes is defined as follows: (1)a graph with n nodes and n edges (2)the degree of every node is 2 (3) each node can reach every other node with these N edges.
Input
Output
题目大意:一棵有n个点的树,删边需要1的费用,增边需要1的费用,问最少需要多少费用才能得到一个环,不能用多余的边(即总共n条边)。
思路:首先我们可以这样考虑:我们先删掉x条边,那么之后再加上x+1条边,形成一个环。我们删掉x条边后,所有的点的度都不能大于2,那么就会出现多条链,再用x+1条边把这些链首尾相接就可以形成一个环。现在问题就转化成了给一棵树,问最少删掉多少条边,使得每个点的度不大于2。然后就是树状DP,用dp[i][0]表示,第i个点,连0个或1个子节点(度小于2)的最小费用。用dp[i][1]表示,第i个点,连0个或1个或2个子节点(度小于等于2)的最小费用。这样对每个点选择是不连或者连一个子节点,还是连两个子节点。然后随便搞,时间复杂度为O(n)。
PS:100W个点我看到好多人栈溢出了所以大家还是写非递归吧(实际上会不会溢出我不知道我没试过我一开始就写非递归)……我极少写非递归可能写得比较挫……
代码(2703MS):
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int MAXN = ;
const int MAXE = MAXN * ; int head[MAXN];
int stk[MAXN], stkp[MAXN], top;
int next[MAXE], to[MAXE];
int ecnt, n, T; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge(int u, int v) {
to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++;
} int dp[MAXN][];
//0:连0 or 1个子节点,1:连两个子节点
int solve() {
top = ;
stk[top] = ; stkp[top] = head[];
while(top > ) {
int &p = stkp[top], u = stk[top];
if(to[p] == stk[top - ]) p = next[p];
if(p) {
int &v = to[p];
++top; stk[top] = v; stkp[top] = head[v];
p = next[p];
}
else {
int min1 = MAXN, min2 = MAXN;
dp[u][] = ;
for(int q = head[u]; q; q = next[q]) {
int &v = to[q];
if(v == stk[top - ]) continue;
++dp[u][];
dp[u][] += min(dp[v][], dp[v][]);
int x = dp[v][] - min(dp[v][], dp[v][]);
if(x < min1) {
min2 = min1;
min1 = x;
}
else min2 = min(min2, x);
}
int best = dp[u][];
dp[u][] = min(dp[u][], best - + min1);
dp[u][] = min(dp[u][], best - + min1 + min2);
--top;
}
}
return * min(dp[][], dp[][]) + ;
} int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
init();
int u, v;
for(int i = ; i < n; ++i) {
scanf("%d%d", &u, &v);
add_edge(u, v);
}
printf("%d\n", solve());
}
}
HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)的更多相关文章
- hduoj 4710 Balls Rearrangement 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4710 Balls Rearrangement Time Limit: 6000/3000 MS (Java/Ot ...
- hduoj 4708 Rotation Lock Puzzle 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4708 Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/O ...
- hduoj 4715 Difference Between Primes 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Time Limit: 2000/1000 MS (J ...
- hduoj 4712 Hamming Distance 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4712 Hamming Distance Time Limit: 6000/3000 MS (Java/Other ...
- hduoj 4707 Pet 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4707 Pet Time Limit: 4000/2000 MS (Java/Others) Memory ...
- hduoj 4706 Children's Day 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4706 Children's Day Time Limit: 2000/1000 MS (Java/Others) ...
- hduoj 4706 Herding 2013 ACM/ICPC Asia Regional Online —— Warmup
hduoj 4706 Children's Day 2013 ACM/ICPC Asia Regional Online —— Warmup Herding Time Limit: 2000/1000 ...
- HDU 4719 Oh My Holy FFF(DP+线段树)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)
Description N soldiers from the famous "*FFF* army" is standing in a line, from left to ri ...
- HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)
Problem Description Zero and One are good friends who always have fun with each other. This time, ...
随机推荐
- 如何对Project Proffesional设置预警灯
Project Proffesional没法一目了然地看到,为了实时看到任务延迟情况,我们必须设置预警灯. 1.添加两个新列“文本1”.“文本2”,重命名为“完成预警”.“进度预警”. 2.右键点击“ ...
- #leetcode刷题之路29- 两数相除
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符.返回被除数 dividend 除以除数 divisor 得到的商. 示例 1:输入: ...
- #leetcode刷题之路9- 回文数
判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1:输入: 121输出: true 示例 2:输入: -121输出: false解释: 从左向右读, 为 ...
- Redis安装与简单配置
一.Redis介绍 1.redis是什么? remote dIctionary server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统.Redis提 ...
- InheritableThreadLocal线程复用
引自:http://www.cnblogs.com/sweetchildomine/p/6575666.html 虽然使用AOP可以获取方法签名,但是如果要获取方法中计算得出的数据,那么就得使用Thr ...
- 解决 Android sdk content loader 0%
第一次遇到这种情况,真的很头痛,没办法 ,是问题就要解决,在网上找了一些方法,归纳了下来. 方法一(关闭后重启): 遇到Eclipse右下角一直显示“Android sdk content loade ...
- JavaScript -- 继承与原型链
JavaScript对象有一个指向一个原型对象的链,当试图访问一个对象的属性的时候,他不仅仅会在该对象上面搜寻,还会搜寻该对象的原型,以及对象的原型的原型,依次层层搜索,直到找到名字匹配的属性或者到达 ...
- sftp上传到远程服务器
开发遇到一个需求,需要将图片通过sftp上传到远程服务器上,之前没用过这个功能,折腾了我好几天才搞定,下面记录下我的处理方法: $sftp = 'ssh2.sftp://';//连接sftp $con ...
- NOIP模拟 candy
题目描述 一天,小 DD 决定买一些糖果.他决定在两家不同的商店中买糖果,来体验更多的口味. 在每家商店中都有 nn 颗糖果,每颗糖果都有一个权值:愉悦度,代表小 DD 觉得这种糖果有多好吃.其中,第 ...
- php PHPEXcel导出
1获取数据,2组装数据,3生成文件. 注意:无法使用ajax生成导出. $settlement = \Yii::$app->request->get('settlement'); $sav ...