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. C语言库函数,头文件

    参看:https://zhidao.baidu.com/question/328173842.html 该文件包含了的C语言标准库函数的定义 stdlib.h里面定义了五种类型.一些宏和通用工具函数. ...

  2. java中volatile关键字的含义--volatile并不能做到线程安全

    在Java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...

  3. amazeui学习笔记--css(HTML元素4)--图片image

    amazeui学习笔记--css(HTML元素4)--图片image 一.总结 1.响应式图片:随着页面宽度而变化 .am-img-responsive class. <img src=&quo ...

  4. Mosquito的优化——订阅树优化(八)

    本文由逍遥子撰写.转发请标注原址: http://blog.csdn.net/houjixin/article/details/46413783 或 http://houjixin.blog.163. ...

  5. js课程 4-11 表格如何实现隔行换色

    js课程 4-11 表格如何实现隔行换色 一.总结 一句话总结:表格奇数行和偶数行判断,赋予不同的样式. 1.表格如何隔行换色? 表格奇数行和偶数行判断,赋予不同的样式. 21 <script& ...

  6. 过滤input框中的特殊字符

    两种方式,我觉得是一样的效果,请看: var charFilter1 = function(str) { var pattern = new RegExp("[`~!@#$^&*() ...

  7. 11.1 Android显示系统框架_framebuffer原理及改进

    1. Android显示系统框架Android Graphic UI with GPU Hardware Accelerationhttps://community.nxp.com/docs/DOC- ...

  8. Shiro基础知识08----拦截器介绍(转)

    1 拦截器介绍 Shiro使用了与Servlet一样的Filter接口进行扩展:所以如果对Filter不熟悉可以参考<Servlet3.1规范>http://www.iteye.com/b ...

  9. 利用java反射将结果集封装成为对象和对象集合

    java反射机制是什么 反射机制是在运行状态中,可以知道任何一个类的属性和方法,并且调用类的属性和方法: 反射机制能够做什么 1.判断运行对象的所属类 2.构造任意一个类的对象 3.获取任意一个类的属 ...

  10. Satisfying memory ordering requirements between partial reads and non-snoop accesses

    A method and apparatus for preserving memory ordering in a cache coherent link based interconnect in ...