HDU 5956 The Elder(斜率优化DP)

来源:互联网 发布:sql select语句查询器 编辑:程序博客网 时间:2024/06/03 19:11

题目链接:



明显是一个斜率优化的形式,套一个斜率优化的板子就好了,重点是dfs的时候要记录操作,并且进行还原。


代码:

#include<bits/stdc++.h>#define xx first#define yy second#define mp make_pairusing namespace std;typedef long long ll;const int MAXN=1e5+5;int tot,head[MAXN],n,p,stk[MAXN],le,ri;ll dp[MAXN],ans,sum[MAXN];struct edge{int to,nxt,w;}E[MAXN*2];void init(){tot=0;memset(head,-1,sizeof(head));}void addedge(int u,int v,int w){E[tot].to=v;E[tot].w=w;E[tot].nxt=head[u];head[u]=tot++;E[tot].to=u;E[tot].w=w;E[tot].nxt=head[v];head[v]=tot++;}ll getUp(int k,int j){return (dp[k]+1LL*sum[k]*sum[k])-(dp[j]+1LL*sum[j]*sum[j]);}ll getDown(int k,int j){return sum[k]-sum[j];}void dfs(int now,int f){vector<pair<int,int> > sv;int l=le,r=ri;while(le+1<ri&&getUp(stk[le+1],stk[le])<=getDown(stk[le+1],stk[le])*2LL*sum[now]){sv.push_back(mp(le,stk[le]));le++;}if(now!=1){dp[now]=dp[stk[le]]+(1LL*sum[now]-sum[stk[le]])*(1LL*sum[now]-sum[stk[le]])+p;ans=max(ans,dp[now]);}while(le+1<ri&&getUp(stk[ri-1],stk[ri-2])*getDown(now,stk[ri-1])>=getUp(now,stk[ri-1])*getDown(stk[ri-1],stk[ri-2])){ri--;sv.push_back(mp(ri,stk[ri]));}stk[ri++]=now;for(int i=head[now];~i;i=E[i].nxt){int v=E[i].to;if(v==f)continue;sum[v]=sum[now]+E[i].w;dfs(v,now);}le=l,ri=r;for(int i=0;i<sv.size();i++){int pos=sv[i].xx,id=sv[i].yy;stk[pos]=id;}}void solve(){init();scanf("%d%d",&n,&p);for(int i=1;i<n;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedge(u,v,w);}le=ri=0;ans=0;dp[1]=-p;dfs(1,0);printf("%lld\n",ans);}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int T;scanf("%d",&T);while(T--){solve();}return 0;}


原创粉丝点击