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. 学习笔记:Vue——自定义指令

    在Vue2.0中,代码复用和抽象的主要形式是组件.然鹅,有的情况下,你仍然需要对普通DOM元素进行底层操作,这时候就会用到自定义指令. 1.举个聚焦输入框的例子,全局注册focus指令 Vue.dir ...

  2. Linux学习总结(4)——Centos6.5使用yum安装mysql——快速上手必备

    第1步.yum安装mysql [root@stonex ~]#  yum -y install mysql-server 安装结果: Installed:     mysql-server.x86_6 ...

  3. 硬件——STM32,ADC篇

    未完,待续...... 也就是stm32f10X系列的adc采集出来的结果是12位的 stm32f10X系列有两个16位adc 关于程序的编写方法:一般  “某某.c文件”:都是用来设置“某某”的一些 ...

  4. 芯片TPS76030、TPS76032、TPS76033、TPS76038、TPS76050 电源芯片

    下图是从网上摘出来的图片:TPS76033 它的作用就是改变电压: 输入电压:3.5V到16V       通过芯片的处理后     输出电压:3.3V 要学会看图,从中提取有用的信息 再看一个数据手 ...

  5. UVA 11646 - Athletics Track || UVA 11817 - Tunnelling the Earth 几何

    题目大意: 两题几何水题. 1.UVA 11646 - Athletics Track 如图,体育场的跑道一圈400米,其中弯道是两段半径相同的圆弧,已知矩形的长宽比例为a:b,求长和宽的具体数值. ...

  6. jni和C++通信中文乱码的问题

    转自 http://www.cnblogs.com/bluesky4485/archive/2011/12/13/2285802.html 首先,需要明确几个关于编码的基本概念: java内部是使用的 ...

  7. 【codeforces 434 div 1 A】Did you mean...

    [链接]h在这里写链接 [题意] 让你维护一段序列. 这段序列,不会出现连续3个以上的辅音. (或者一块全是辅音则也可以) (用空格可以断开连续次数); 要求空格最小. [题解] 模拟着,别让它出现连 ...

  8. 【习题 5-9 UVA - 1596】Bug Hunt

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] map模拟 map<string,int>记录每个数组的大小 map <pair<string, int&g ...

  9. AdminLTE的使用(转)

    官方文档link1.AdminLTE的必要配置文件<!-- Tell the browser to be responsive to screen width --> <meta c ...

  10. 【7001】n阶法雷序列

    Time Limit: 10 second Memory Limit: 2 MB 问题描述      对任意给定的一个自然数n(n<=100),将分母小于等于n的不可约的真分数按上升的次序排序, ...