[2015hdu多校联赛补题]hdu5293 Tree chain problem
2015-08-02 23:12
453 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5293
题意:给你一棵n个点的树,和一些该树上的树链,每个树链有一定的权值,要求选出一些不相交的树链,使他们的权值和尽量大
解:
树形dp,dp[x]表示以x为根节点的子树的解,那么就可以基于在当前结点对树链的选和不选进行dp
现在有两个问题:
1、在树链上的哪个点进行选择?
2、选和不选分别如何操作?
对于第一个问题,粗略想一下(在解决问题二的时候会发现),树链上最浅的一个点(也就是树链两端的lca)上选择是可行的
对于第二个问题,(假设现在在点u)不选的话,dp[u]=Sum(dp[v])(v为u的子节点),用sum[u]记录Sum(dp[v])(v为u的子节点),有dp[u]=sum[u]
选择的话,对于每一个lca在u点的树链c,
dp[u]=max(dp[u],Sum(dp[v1])+c.w(v1为c上所有节点的子节点, c.w为该链的权值))
dp[u]=max(dp[u],Sum(sum[x])-Sum(dp[x])+c.w(x为c上所有节点, c.w为该链的权值))
这个链上所有节点的某值和,用dfs序+树状数组维护一下就好了
hdu 5293
题意:给你一棵n个点的树,和一些该树上的树链,每个树链有一定的权值,要求选出一些不相交的树链,使他们的权值和尽量大
解:
树形dp,dp[x]表示以x为根节点的子树的解,那么就可以基于在当前结点对树链的选和不选进行dp
现在有两个问题:
1、在树链上的哪个点进行选择?
2、选和不选分别如何操作?
对于第一个问题,粗略想一下(在解决问题二的时候会发现),树链上最浅的一个点(也就是树链两端的lca)上选择是可行的
对于第二个问题,(假设现在在点u)不选的话,dp[u]=Sum(dp[v])(v为u的子节点),用sum[u]记录Sum(dp[v])(v为u的子节点),有dp[u]=sum[u]
选择的话,对于每一个lca在u点的树链c,
dp[u]=max(dp[u],Sum(dp[v1])+c.w(v1为c上所有节点的子节点, c.w为该链的权值))
dp[u]=max(dp[u],Sum(sum[x])-Sum(dp[x])+c.w(x为c上所有节点, c.w为该链的权值))
这个链上所有节点的某值和,用dfs序+树状数组维护一下就好了
/* * Problem: * Author: SHJWUDP * Created Time: 2015/8/2 星期日 22:07:32 * File Name: 233.cpp * State: * Memo: */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; struct Edge { int u, v; Edge(int u, int v):u(u), v(v){} }; struct Chain { int a, b, w; int lca; }; struct Fenwick { int n; vector<int> c; void init(int n) { this->n=n; c.assign(n+1, 0); } int lowbit(int x) { return x & -x; } void add(int x, int v) { while(x<=n) { c[x]+=v; x+=lowbit(x); } } int getsum(int x) { int res=0; while(x>0) { res+=c[x]; x-=lowbit(x); } return res; } } fw1, fw2; int n, m; vector<Edge> edges; vector<vector<int> > G; vector<Chain> chain; vector<int> ln, rn, dep, dp, sum; vector<vector<int> > fa, arr; int root, cnt; void init(int sz) { edges.clear(); G.assign(sz, vector<int>(0)); chain.resize(sz); ln.resize(sz); rn.resize(sz); dep.resize(sz); dp.resize(sz); sum.resize(sz); fa.assign(sz, vector<int>(20)); arr.assign(sz, vector<int>(0)); fw1.init(sz<<1); fw2.init(sz<<1); } void addEdge(int u, int v) { edges.push_back(Edge(u, v)); G[u].push_back(edges.size()-1); } void dfs1(int u) { ln[u]=++cnt; for(int k=1; k<20; k++) fa[u][k]=fa[fa[u][k-1]][k-1]; for(int i : G[u]) { Edge & e=edges[i]; if(e.v==fa[u][0]) continue; fa[e.v][0]=u; dep[e.v]=dep[u]+1; dfs1(e.v); } rn[u]=++cnt; } int lca(int u, int v) { if(dep[u]<dep[v]) swap(u, v); for(int k=19; k>=0; k--) { if(dep[fa[u][k]]>=dep[v]) { u=fa[u][k]; } } if(u==v) return u; for(int k=19; k>=0; k--) { if(fa[u][k]!=fa[v][k]) { u=fa[u][k]; v=fa[v][k]; } } return fa[u][0]; } void dfs2(int u) { dp[u]=sum[u]=0; for(int i : G[u]) { Edge & e=edges[i]; if(e.v==fa[u][0]) continue; dfs2(e.v); sum[u]+=dp[e.v]; } dp[u]=sum[u]; for(int i : arr[u]) { Chain & c=chain[i]; int tmp=fw1.getsum(ln[c.a])+fw1.getsum(ln[c.b]) -fw2.getsum(ln[c.a])-fw2.getsum(ln[c.b])+sum[u]; dp[u]=max(dp[u], tmp+c.w); } fw1.add(ln[u], sum[u]); fw1.add(rn[u], -sum[u]); fw2.add(ln[u], dp[u]); fw2.add(rn[u], -dp[u]); } int main() { #ifndef ONLINE_JUDGE freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); init(n+1); for(int i=1; i<n; i++) { int a, b; scanf("%d%d", &a, &b); addEdge(a, b); addEdge(b, a); } root=1; cnt=0; dep[root]=0; fa[root][0]=root; dfs1(root); for(int i=0; i<m; i++) { scanf("%d%d%d", &chain[i].a, &chain[i].b, &chain[i].w); chain[i].lca=lca(chain[i].a, chain[i].b); arr[chain[i].lca].push_back(i); } dfs2(root); printf("%d\n", dp[root]); } return 0; }
hdu 5293
相关文章推荐
- Check GitLab API access: FAILED: Failed to connect to internal API
- public static void main(String arg[]) 详细解释
- bower failed: UNABLE_TO_VERIFY_LEAF_SIGNATURE
- 70. Climbing Stairs
- repair windows ntfs part on ubuntu
- 《MFC游戏开发》笔记九 游戏中的碰撞判定初步&怪物运动简单AI
- hdoj 1022Train Problem I
- HDU 1789 Doing Homework again 【队列+贪心】
- Snail—算法学习之内部排序
- HUAS Summer Trainning #3 N
- HUAS Summer Trainning #3 M
- HUAS Summer Trainning #3 L
- Snail—算法学习之最大公约、最小公倍
- HUAS Summer Trainning #3 K
- Airplay vs DLNA vs Miracast
- HUAS Summer Trainning #3 E
- N!Again
- Snail—算法学习之初始递归
- orcale 约束 constraint
- [leedcode 172] Factorial Trailing Zeroes