HDU 树型dp
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的更多相关文章
- HDU 5905 Black White Tree(树型DP)
题目链接 Black White Tree 树型DP,设$f[i][j]$为以$i$为根的子树中大小为$j$的连通块中可以包含的最小黑点数目. $g[i][j]$为以$i$为根的子树中大小为$j$的 ...
- HDU 5293 Train chain Problem - 树链剖分(树状数组) + 线段树+ 树型dp
传送门 题目大意: 一颗n个点的树,给出m条链,第i条链的权值是\(w_i\),可以选择若干条不相交的链,求最大权值和. 题目分析: 树型dp: dp[u][0]表示不经过u节点,其子树的最优值,dp ...
- 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 ...
- HDU_1011_Starship Troopers_树型dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 Starship Troopers Time Limit: 10000/5000 MS (Jav ...
- HDU_1520_Anniversary party_树型dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 Anniversary party Time Limit: 2000/1000 MS (Java ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...
- 【XSY1905】【XSY2761】新访问计划 二分 树型DP
题目描述 给你一棵树,你要从\(1\)号点出发,经过这棵树的每条边至少一次,最后回到\(1\)号点,经过一条边要花费\(w_i\)的时间. 你还可以乘车,从一个点取另一个点,需要花费\(c\)的时间. ...
- 洛谷P3354 Riv河流 [IOI2005] 树型dp
正解:树型dp 解题报告: 传送门! 简要题意:有棵树,每个节点有个权值w,要求选k个节点,最大化∑dis*w,其中如果某个节点到根的路径上选了别的节点,dis指的是到达那个节点的距离 首先这个一看就 ...
随机推荐
- 黑马day01 xml 的解析方式
XML编程:利用java程序去增删改查(CRUD)xml中的数据 解析思想: dom解析 sax解析 基于这两种解析思想市面上就有了非常多的解析api sun jaxp既有dom方式也有sax方式,而 ...
- Codeforces #28 C.Bath Queue (概率dp)
Codeforces Beta Round #28 (Codeforces format) 题目链接: http://codeforces.com/contest/28/problem/C 题意: 有 ...
- WCF学习笔记——对象序列化
当试图通过Web服务.WCF这样的远程处理技术将一个对象复制到远端时,具有对类型序列化的能力很关键. 一 序列化基础 序列化描述了持久化或传输一个对象的状态到流的过程(.NET将对象序列化到流,流是字 ...
- Codeforces Round #Pi (Div. 2) B Berland National Library
B. Berland National Library time limit per test1 second memory limit per test256 megabytes inputstan ...
- 使用u盘量产工具修复写保护的u盘
自己的u盘突然提示写保护,而且也没有写保护开关,怎么都写不进文件,试了很多办法都无法去除写保护,最后找了一个u盘量产工具,搞定: 插上u盘后,会检测到u盘,点“开始"后静静等待它完成,u盘又 ...
- 用Java将字符串的首字母转换大小写
在项目开发的时候会需要统一字符串的格式,比如首字母要求统一大写或小写,那用Java如何实现这一功能?下面一起来学习学习. 话不多说,直接上代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 ...
- 3、linux下Socket编程-TCP/UDP
1.什么是Socket 网络的 Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返 回一个整型的Socke ...
- stm32的dac
- php xml转数组,数组转xml,array转xml,xml转array
//数组转XML function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key=>$val) ...
- angular动画知识点以及代码样例
原文地址 https://www.jianshu.com/p/4400174072e2 大纲 1.angular动画的相关概念 2.angular动画的绑定方式 3.angular动画代码实例 1.a ...