HDU7458-启发式合并优化DP
link:https://acm.hdu.edu.cn/showproblem.php?pid=7458
题意:给一棵树,每个点有点权
对每条路径
算答案的时候刚好多减去一个 map
(甚至可以是unordered
的)维护,每跳一层就给这个子树做一个全局加
对于直接从
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define endl '\n' #define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; typedef long long ll; const int N=2e5+5; int n,c[N]; ll f[N][2],g[N],w[N]; vector<vector<int>> G; int bl[N]; ll tag[N]; map<int,ll> mp[N]; void upd(ll &x,ll y){x=max(x,y);} void dfs(int x,int fa){ f[x][0]=f[x][1]=g[x]=0; for(auto to:G[x])if(to!=fa){ dfs(to,x); f[x][0]+=g[to]; } for(auto v:G[x])if(v!=fa){ if(mp[bl[v]].count(c[x]))upd(f[x][1],(mp[bl[v]][c[x]]+tag[bl[v]])+f[x][0]+w[x]); //merge v to x; if(mp[bl[v]].size()>mp[bl[x]].size())swap(bl[v],bl[x]); //calc for(auto [col,val]:mp[bl[v]]){ if(mp[bl[x]].count(col)) upd(f[x][1],(val+tag[bl[v]])+(mp[bl[x]][col]+tag[bl[x]])+f[x][0]); } //merge for(auto [c,val]:mp[bl[v]]){ if(mp[bl[x]].count(c))upd(mp[bl[x]][c],val+tag[bl[v]]-tag[bl[x]]); else mp[bl[x]][c]=val+tag[bl[v]]-tag[bl[x]]; } } if(mp[bl[x]].count(c[x]))upd(mp[bl[x]][c[x]],w[x]-tag[bl[x]]); else mp[bl[x]][c[x]]=w[x]-tag[bl[x]]; g[x]=max(f[x][0],f[x][1]); tag[bl[x]]+=f[x][0]-g[x]; } void solve(){ cin>>n; rep(i,1,n)cin>>c[i]; rep(i,1,n)cin>>w[i]; G=vector<vector<int>> (n+1); rep(i,1,n)bl[i]=i,tag[i]=0,mp[i].clear(); rep(i,1,n-1){ int u,v; cin>>u>>v; G[u].push_back(v); G[v].push_back(u); } dfs(1,-1); // rep(i,1,n)cout<<f[i][0]<<' '<<f[i][1]<<' '<<g[i]<<endl; cout<<g[1]<<endl; } int main(){ fastio; int tc;cin>>tc; while(tc--)solve(); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步