HDU 5293 Tree chain problem - 树形dp&树状数组优化
2016-02-18 21:24
501 查看
题目描述
1 ≤n,m≤ 100000。
Source:2015 Multi-University Training Contest 1
转移方程:
枚举链的两端点的lca为u的链,记w为当前链的价值
f[u]=max{∑f[u.son],w+∑k为当前链上的节点的儿子f[k]}f[u]=max\{{\sum{f[u.son]} , w+\sum_{k为当前链上的节点的儿子}{f[k]}} \}
时间复杂度O((n+m)*n),过不了,选择优化,记sum[u]为u的所有儿子v的f[v]之和,得到:
f[u]=max{∑f[u.son],w+∑j为当前链上的节点sum[j]−f[j]}f[u]=max\{{\sum{f[u.son]} , w+\sum_{j为当前链上的节点}{sum[j]-f[j]}} \}
(链上的点会在它的父亲的sum[]中多加,要再减去)
可根据dfs序维护树状数组来实现优化。
题目大意:
给定一棵有 n 个点的树,以及 m 条树链,其中第 i 条树链 的价值为 wi,请选择一些没有公共点的树链,使得价值和最大。1 ≤n,m≤ 100000。
Source:2015 Multi-University Training Contest 1
分析:
设f[u]为u为根的子树上选择没有公共点的树链所得的最大价值和。转移方程:
枚举链的两端点的lca为u的链,记w为当前链的价值
f[u]=max{∑f[u.son],w+∑k为当前链上的节点的儿子f[k]}f[u]=max\{{\sum{f[u.son]} , w+\sum_{k为当前链上的节点的儿子}{f[k]}} \}
时间复杂度O((n+m)*n),过不了,选择优化,记sum[u]为u的所有儿子v的f[v]之和,得到:
f[u]=max{∑f[u.son],w+∑j为当前链上的节点sum[j]−f[j]}f[u]=max\{{\sum{f[u.son]} , w+\sum_{j为当前链上的节点}{sum[j]-f[j]}} \}
(链上的点会在它的父亲的sum[]中多加,要再减去)
可根据dfs序维护树状数组来实现优化。
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define MAXN 100000 #define MAXM 100000 #define MAXLOG 20 typedef long long LL; struct node{ int v; node *next; }edge[MAXN*2+10],*adj[MAXN+10],*ecnt=&edge[0]; vector<int> pnt[MAXN+10]; int n,m,LogN,chain[MAXM+10][3]; int fa[MAXN+10],dep[MAXN+10],P[MAXN+10][MAXLOG+10]; int in[MAXN+10],out[MAXN+10],cntd; LL c[2*MAXN+10],f[MAXN+10]; void Init() { memset(adj,0,sizeof adj); ecnt=&edge[0]; memset(pnt,0,sizeof pnt); memset(fa,0,sizeof fa); memset(dep,0,sizeof dep); memset(f,0,sizeof f); cntd=0; memset(c,0,sizeof c); } void addedge(int u,int v) { node *p=++ecnt; p->v=v; p->next=adj[u]; adj[u]=p; } void dfs(int u,int prev,int L) { fa[u]=prev; dep[u]=L; for(node *p=adj[u];p;p=p->next){ if(p->v==fa[u]) continue; dfs(p->v,u,L+1); } } void LCA_pre() { memset(P,-1,sizeof P); for(int i=1;i<=n;i++) P[i][0]=fa[i]; for(LogN=0;(1<<LogN)<=n;LogN++); LogN--; for(int j=1;j<=LogN;j++){ for(int i=1;i<=n;i++) if(P[i][j-1]!=-1) P[i][j]=P[P[i][j-1]][j-1]; } } int LCA(int x,int y) { if(dep[x]<dep[y]) swap(x,y); int Logx; for(Logx=0;(1<<Logx)<=dep[x];Logx++); Logx--; for(int i=Logx;i>=0;i--) if(dep[P[x][i]]>=dep[y]) x=P[x][i]; if(x==y) return x; for(int i=Logx;i>=0;i--) if(P[x][i]!=P[y][i]) x=P[x][i],y=P[y][i]; return fa[x]; } void read() { int x,y; scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } dfs(1,0,1); LCA_pre(); for(int i=1;i<=m;i++){ scanf("%d%d%d",&chain[i][0],&chain[i][1],&chain[i][2]); int lca=LCA(chain[i][0],chain[i][1]); pnt[lca].push_back(i); } } int lowbit(int x){ return x&(-x); } void Update(int x,LL d){ while(x<=2*n){ c[x]+=d; x+=lowbit(x); } } LL Getsum(int x){ LL ret=0; while(x){ ret+=c[x]; x-=lowbit(x); } return ret; } void DP(int u) //dfs for dp on the tree { LL g_u=0; in[u]=++cntd; for(node *p=adj[u];p;p=p->next){ if(p->v==fa[u]) continue; DP(p->v); g_u+=f[p->v]; } out[u]=++cntd; Update(in[u],g_u); Update(out[u]+1,-g_u); f[u]=g_u; int side=pnt[u].size(); for(int i=0,num;i<side;i++){ num=pnt[u][i]; f[u]=max(f[u],Getsum(out[chain[num][0]])+Getsum(out[chain[num][1]])+1LL*chain[num][2]-g_u); } Update(in[u],-f[u]); Update(out[u]+1,f[u]); } int main() { int T; scanf("%d",&T); while(T--){ Init(); read(); DP(1); printf("%I64d\n",f[1]); } }
相关文章推荐
- zabbix使用sendEmail发送告警邮件
- Organize Your Train part II POJ 3007 (哈希&链式解决冲突)
- C/C++程序中的profile http://blog.csdn.net/cnjet/article/details/2617403
- 11. Container With Most Water
- aidl引用类作为函数的返回值
- INSTALL_FAILED_OLDER_SDK
- grails一对一关联关系
- GDAL应用-gdal_merge.py
- ORA-00245: control file backup failed; target is likely on a local file system
- DataIntegration windows7 64 安装
- mbstring.funcoverload fail
- HDU1839---Delay Constrained Maximum Capacity Path(SPFA+vector+二分)
- Python 18.4 aiohttp
- 斗地主智能(AI)出牌算法
- Failed to read schema document 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd'问题解决方法
- Could not find a storyboard named 'Main' in bundle NSBundle
- Win10 UWP开发系列:实现Master/Detail布局
- 假设将synthesize省略,语义特性声明为assign retain copy时,自己实现setter和getter方法
- RabbitMQ消息队列(一): Detailed Introduction 详细介绍
- XSS过滤器Bypass的一些姿势 - xiaix