HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)
2017-09-13 21:48
363 查看
Tree chain problem
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1798 Accepted Submission(s): 585
Problem Description
Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are m chain on the tree, Each chain has a certain weight. Coco would like to pick out some chains any two of which do not share common vertices.
Find out the maximum sum of the weight Coco can pick
Input
The input consists of several test cases. The first line of input gives the number of test cases T (T<=10).For each tests:
First line two positive integers n, m.(1<=n,m<=100000)
The following (n - 1) lines contain 2 integers ai bi denoting an edge between vertices ai and bi (1≤ai,bi≤n),
Next m lines each three numbers u, v and val(1≤u,v≤n,0<val<1000), represent the two end points and the weight of a tree chain.
Output
For each tests:A single integer, the maximum number of paths.
Sample Input
1 7 3 1 2 1 3 2 4 2 5 3 6 3 7 2 3 4 4 5 3 6 7 3
Sample Output
6Hint
Stack expansion program: #pragma comment(linker, "/STACK:1024000000,1024000000")
Author
FZUACM
Source
2015 Multi-University Training Contest 1
对于每条链u,v,w,我们只在lca(u,v)的顶点上处理它
让dp[i]表示以i为根的子树的最大值,sum[i]表示dp[vi]的和(vi为i的儿子们)
则i点有两种决策,一种是不选以i为lca的链,则dp[i]=sum[i]。
另一种是选一条以i为lca的链,那么有转移方程:dp[i]=sigma(dp[vj])+sigma(sum[kj])+w。(sigma表示累加,vj表示那些不在链上的孩子们,kj表示在链上的孩子们)
为了便于计算,我们处理出dp[i]=sum[i]-sigma(dp[k]-sum[k])+w=sum[i]+sigma(sum[k]-dp[k])+w。
利用dfs序和树状数组可以logn算出sigma(sum[k]-dp[k])。
//2017-09-13 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int N = 210000; const int LOG_N = 22; int head , tot; struct Edge{ int v, next; }edge[N<<1]; void add_edge(int u, int v){ edge[tot].v = v; edge[tot].next = head[u]; head[u] = tot++; } int in , out , idx, depth , father [LOG_N]; void dfs(int u, int fa){ in[u] = ++idx; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].v; if(v == fa)continue; depth[v] = depth[u]+1; father[v][0]= u; for(int j = 1; j < LOG_N; j++) father[v][j] = father[father[v][j-1]][j-1]; dfs(v, u); } out[u] = ++idx; } int tree ; int lowbit(int x){ return x&(-x); } void add(int pos, int val){ for(int i = pos; i <= N; i+=lowbit(i)) tree[i] += val; } int query(int l){ int sum = 0; for(int i = l; i > 0; i-=lowbit(i)) sum += tree[i]; return sum; } int lca(int u, int v){ if(depth[u] < depth[v]) swap(u, v); for(int i = LOG_N-1; i >= 0; i--){ if(depth[father[u][i]] >= depth[v]) u = father[u][i]; } if(u == v)return u; for(int i = LOG_N-1; i >= 0; i--){ if(father[u][i] != father[v][i]){ u = father[u][i]; v = father[v][i]; } } return father[u][0]; } struct Chain{ int u, v, w; }chain ; vector<int> vec ; int dp , sum ; void solve(int u, int fa){ dp[u] = sum[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].v; if(v == fa)continue; solve(v, u); sum[u] += dp[v]; } dp[u] = sum[u]; for(auto &pos: vec[u]){ int a = chain[pos].u; int b = chain[pos].v; int c = chain[pos].w; dp[u] = max(dp[u], sum[u]+query(in[a])+query(in[b])+c); } add(in[u], sum[u]-dp[u]); add(out[u], dp[u]-sum[u]); } int T, n, m; void init(){ tot = 0; idx = 0; depth[1] = 1; for(int i = 1; i <= n; i++) vec[i].clear(); memset(head, -1, sizeof(head)); memset(dp, 0, sizeof(0)); memset(sum, 0, sizeof(0)); memset(tree, 0, sizeof(tree)); } int main() { freopen("inputB.txt", "r", stdin); scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); init(); int u, v; for(int i = 0; i < n-1; i++){ scanf("%d%d", &u, &v); add_edge(u, v); add_edge(v, u); } dfs(1, 0); for(int i = 0; i < m; i++){ scanf("%d%d%d", &chain[i].u, &chain[i].v, &chain[i].w); vec[lca(chain[i].u, chain[i].v)].push_back(i); } solve(1, 0); printf("%d\n", dp[1]); } return 0; }
相关文章推荐
- hdu5293(2015多校1)--Tree chain problem(树状dp)
- hdu5293(2015多校1)--Tree chain problem(树状dp)
- HDU3534(SummerTrainingDay13-C tree dp)
- bzoj 3594: [Scoi2014]方伯伯的玉米田 二维树状数组优化dp
- 【二维树状数组优化dp】[Scoi2014] bzoj3594方伯伯的玉米田
- SGU 134 数组模拟树状dp
- NOIP模拟题 2016.9.3 [数论] [逆序对] [树状数组] [树形dp]
- 树状数组(Binary Indexed Tree)
- hdu5542(树状数组优化dp)
- USACO-Section 3.3 Home on the Range (树状数组||DP)
- hdu5542 树状数组优化dp
- Binary_Indexed_Tree(树状数组)
- 【BZOJ1264】[AHOI2006]基因匹配Match【DP】【LCS】【树状数组】
- Codeforces 461B - Appleman and Tree 树状DP
- ZOJ 4008 Yet Another Tree Query Problem [想法+树状数组]
- ZOJ 4008 Yet Another Tree Query Problem 树状数组 离线处理
- hdu 2227(树状数组优化dp)
- 【bzoj4822/bzoj1935】[Cqoi2017]老C的任务/[Shoi2007]Tree 园丁的烦恼 树状数组
- BZOJ 1935: [Shoi2007]Tree 园丁的烦恼 [树状数组 离线 离散化]
- [DP] [2D2D优化] [二维树状数组] [SCOI2014] 方伯伯的玉米田