HDU 4123 Bob's Race

题意:定义每个点的值为它到树上最远点的距离,每次询问q,回答最长的极值差小于等于q且编号连续的一段点的长度。

题解:求距离两次dp,求极值ST表+尺取法。

HDU 4514 湫湫系列故事——设计风景线

题意:给一张图,如果有环,输出YES,否则为一个森林,求出每个树的直径,输出最大值。

题解:并查集判环,两边dfs找直径。

POJ 1655 Balancing Act

题意:删掉一个点,使得分出的最大连通块大小最小

题解:求重儿子,用重儿子大小和(n-sze[该子树])去更新答案。

HDU 4714 Tree2cycle

题意:删边或加边都有1的费用,求将一棵树变成一个环的最小费用。

题解:贪心:将树拆成链再连成环。具体:对树进行dfs,如果一个节点有大于等于2个子节点,就删边保留两个子节点,并删除该节点与父亲的连边(特判根节点),最后答案为删边*2+1(连接图的首尾)。

code

hdu4123

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 50050
#define maxm 550
#define oo 0x3f3f3f3f
int n, m;
int ecnt, adj[maxn], go[maxn*2], len[maxn*2], nxt[maxn*2];
int dp[maxn][5]; //0向下最大,1向下次大,2向上最大
int delta[maxn], Log[25], ans;
int mx[maxn][25], mn[maxn][25]; inline void initLog() {
Log[0] = -1;
for(int i = 1; i <= 50005; i++) Log[i] = Log[i >> 1] + 1;
} inline void addEdge(int u, int v, int c) {
nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v, len[ecnt] = c;
} inline void init() {
for(int i = 1; i <= n; i++) adj[i] = 0;
ecnt = 0;
for(int i = 1; i <= n; i++) {
dp[i][0] = dp[i][1] = 0;
dp[i][2] = 0;
}
} inline void dfs1(int u, int f) {
for(int e = adj[u]; e; e = nxt[e]) {
int v = go[e];
if(v == f) continue;
dfs1(v, u);
if(dp[v][0] + len[e] > dp[u][0]) {
dp[u][1] = dp[u][0];
dp[u][0] = dp[v][0] + len[e];
} else if(dp[v][0] + len[e] > dp[u][1]) {
dp[u][1] = dp[v][0] + len[e];
}
}
} inline void dfs2(int u, int f) {
for(int e = adj[u]; e; e = nxt[e]) {
int v = go[e];
if(v == f) continue;
int t = ((dp[u][0] == dp[v][0] + len[e]) ? dp[u][1] : dp[u][0]);
dp[v][2] = max(t + len[e], dp[u][2] + len[e]);
dfs2(v, u);
}
} inline int query(int l, int r){
int k = Log[r - l + 1];
int maxx = max(mx[l][k], mx[r - (1 << k) + 1][k]);
int minn = min(mn[l][k], mn[r - (1 << k) + 1][k]);
return maxx - minn;
} int main() {
initLog();
while(scanf("%d%d", &n, &m) != EOF) {
if(!n && !m) return 0;
init();
for(int i = 1; i < n; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
addEdge(x, y, z);
addEdge(y, x, z);
}
dfs1(1, 0);
dfs2(1, 0);
// for(int i = 1; i <= n; i++) cout<<i<<" "<<dp[i][0]<<" "<<dp[i][1]<<" "<<dp[i][2]<<endl;
for(int i = 1; i <= n; i++) mx[i][0] = mn[i][0] = max(dp[i][0], dp[i][2]);
for(int j = 1; j <= Log[n]; j++)
for(int i = 1; i <= n; i++){
if(i + (1 << j) - 1 <= n){
mx[i][j] = max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]);
mn[i][j] = min(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]);
}
}
for(int i = 1; i <= m; i++) {
int q, ans = 0;
scanf("%d", &q);
int head = 1;
for(int j = 1; j <= n; j++) {
while(head <= j && query(head, j) > q) head++;
ans = max(ans, j - head + 1);
}
printf("%d\n",ans);
}
}
}

hdu4514

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 100050, M = 1000050;
int n, m;
int ecnt, adj[N], go[M << 1], nxt[M << 1], len[M << 1];
int vst[N], vt, anc[N], pos1, pos2, dis, ans; inline void addEdge(int u, int v, int l){
nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v, len[ecnt] = l;
} inline void dfs(int u, int f, int l, int &pos){
vst[u] = vt;
if(l > dis){
pos = u;
dis = l;
}
for(int e = adj[u]; e; e = nxt[e]){
int v = go[e];
if(v == f) continue;
dfs(v, u, l + len[e], pos);
}
} inline int getAnc(int x){
return x == anc[x] ? x :(anc[x] = getAnc(anc[x]));
} int main(){
while(~scanf("%d%d", &n, &m)){
for(int i = 1; i <= n; i++) anc[i] = i, adj[i] = 0; ecnt = ans = 0;
bool flag = true;
for(int i = 1; i <= m; i++){
int x, y, z; scanf("%d%d%d", &x, &y, &z);
if(!flag) continue;
int fx = getAnc(x), fy = getAnc(y);
if(fx == fy) flag = false;
if(flag) addEdge(x, y, z), addEdge(y, x, z), anc[fx] = fy;
}
if(!flag){
printf("YES\n");
continue;
}
vt++;
for(int i = 1; i <= n; i++){
if(vst[i] == vt) continue;
dis = 0, pos1 = 0, pos2 = 0;
dfs(i, 0, 0, pos1);
dis = 0;
dfs(pos1, 0, 0, pos2);
ans = max(dis, ans);
}
printf("%d\n", ans);
}
}

poj1655

待填

hdu4714

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read(){
int i = 0, f = 1; char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
return i * f;
} inline void wr(int x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) wr(x / 10);
putchar(x % 10 + '0');
}
const int N = 1000050;
int T, n;
int ecnt, adj[N], go[N << 1], nxt[N << 1], cnt; inline void addEdge(int u, int v){
nxt[++ecnt] = adj[u], adj[u] = ecnt, go[ecnt] = v;
} inline int dfs(int u, int f){
int ret = 0;
for(int e = adj[u]; e; e = nxt[e]){
int v = go[e];
if(v == f) continue;
ret += dfs(v, u);
}
if(ret >= 2){
cnt += ret - 2 + (u == 1 ? 0 : 1);
return 0; //删去与父亲节点的边
}
return 1;
} int main(){
T = read();
while(T--){
n = read();
for(int i = 1; i <= n; i++) adj[i] = 0; ecnt = 0;
for(int i = 1; i < n; i++){
int x = read(), y = read();
addEdge(x, y);
addEdge(y, x);
}
cnt = 0;
dfs(1, 0);
wr(cnt * 2 + 1);
putchar('\n');
}
}

HDU 树型dp的更多相关文章

  1. HDU 5905 Black White Tree(树型DP)

    题目链接  Black White Tree 树型DP,设$f[i][j]$为以$i$为根的子树中大小为$j$的连通块中可以包含的最小黑点数目. $g[i][j]$为以$i$为根的子树中大小为$j$的 ...

  2. HDU 5293 Train chain Problem - 树链剖分(树状数组) + 线段树+ 树型dp

    传送门 题目大意: 一颗n个点的树,给出m条链,第i条链的权值是\(w_i\),可以选择若干条不相交的链,求最大权值和. 题目分析: 树型dp: dp[u][0]表示不经过u节点,其子树的最优值,dp ...

  3. HDU_1561_The more, The Better_树型dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 The more, The Better Time Limit: 6000/2000 MS (J ...

  4. HDU_1011_Starship Troopers_树型dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 Starship Troopers Time Limit: 10000/5000 MS (Jav ...

  5. HDU_1520_Anniversary party_树型dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 Anniversary party Time Limit: 2000/1000 MS (Java ...

  6. POJ3659 Cell Phone Network(树上最小支配集:树型DP)

    题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...

  7. POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断

    好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...

  8. 【XSY1905】【XSY2761】新访问计划 二分 树型DP

    题目描述 给你一棵树,你要从\(1\)号点出发,经过这棵树的每条边至少一次,最后回到\(1\)号点,经过一条边要花费\(w_i\)的时间. 你还可以乘车,从一个点取另一个点,需要花费\(c\)的时间. ...

  9. 洛谷P3354 Riv河流 [IOI2005] 树型dp

    正解:树型dp 解题报告: 传送门! 简要题意:有棵树,每个节点有个权值w,要求选k个节点,最大化∑dis*w,其中如果某个节点到根的路径上选了别的节点,dis指的是到达那个节点的距离 首先这个一看就 ...

随机推荐

  1. (入门整理学习一)Asp.net core

    1.安装.net code SDK,vs Code;vs code c#插件可在软件扩展 (我网盘有)  vs2015上安装教程:http://www.cnblogs.com/wangrudong00 ...

  2. DB2 概览

    2006:IBM公布DB2.9.将数据库领域带入XML时代.IT建设业已进入SOA(Service-Oriented Architecture)时代.实现SOA.其核心难点是顺畅解决不同应用间的数据交 ...

  3. amazeui学习笔记--css(HTML元素1)--按钮Button

    amazeui学习笔记--css(HTML元素1)--按钮Button 一.总结 1.button的基本使用:a.am-btn 在要应用按钮样式的元素上添加 .am-btn,b.颜色 再设置相应的颜色 ...

  4. Cmake 实现debug和release lib依赖项处理

    一.说明 最近用cmake开发东西,编译vs时候,发现debug和release版本的lib库的依赖项问题,故此小结一下.若有不对之处,还请看官多多指教. 使用的工程有自己编写的工程,也有借用第三方库 ...

  5. 【例题5-4 UVA - 156】Ananagrams

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每个字符串如果每个字符按照升序排一下.假设他们能够互相变化. 则肯定是一样的. 根据这个东西,用一个map来判重就好. [错的次数] ...

  6. 【z12】&&【b092】hankson的趣味问题

    描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现 在,刚刚放学回家的 Hankson 正在思考一个有趣的问题. 今天在课堂上,老师讲解了 ...

  7. Android 底部TabActivity(0)——开篇(界面分析|系列文章文件夹)

    当下主流的软件没有一个统一明白的风格,App框架什么样的都有,但个人钟情于页面底部Tab分签架构,移动设备的屏幕尽管越来越大,可是显示的内容还是有限,为了能展示很多其它的内容,方便简洁的操作习惯中Ta ...

  8. position:absolute和margin:auto 连用实现元素水平垂直居中

    有时候,要实现一些元素水平垂直都居中,这部分元素呢 可能大小未知,例如一些图片或者是一些未知大小的块元素. 利用绝对定位可以将要居中的元素脱离文档流. position: absolute; left ...

  9. 利用IIdentify接口实现点选和矩形选择要素

    duckweeds 原文利用IIdentify接口实现点选和矩形选择要素 Identify接口定义了获得要素图层单个要素的属性的捷径方法.它有一个Identify方法,返回一个IArray数组对象. ...

  10. 数学分析告诉偶们什么(vamei)

    1]人生的痛苦在于追求错误的东西.所谓追求错误的东西,就是你在无限趋近于它的时候,才猛然发现,你和它是不连续的. 2]人和人就像数轴上的有理数点,彼此能够靠得非常近非常近,但你们之间始终存在隔阂. 3 ...