Codeforces 1083 A. The Fair Nut and the Best Path(树形DP)

Flavia ·
更新时间:2024-11-14
· 728 次阅读

codeforces每日一练。
题意:
给一棵树,每个点有一个点权,每条边有一个边权,求一条链使得点权和-边权和最大。

思路:

由于我没看清楚题意,以为是求联通子图的点权和-边权和最大,用link-cut-tree写换根,wa10了两发。 回头重新看了一下题意,这不就是求最长链的树形dp裸题吗?

代码如下:

#include #define ll long long #define inf 0x3f3f3f3f #define mod 1000000007 #define PI acos(-1) #define fi first #define se second #define lowbit(x) (x&(-x)) #define mp make_pair #define pb push_back #define ins insert #define si size() #define E exp(1.0) #define fixed cout.setf(ios::fixed) #define fixeds(x) setprecision(x) #pragma GCC optimize(2) using namespace std; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch>= 1;}return ans%p;}ll Inv(ll x,ll p){return qp(x,p-2,p);} ll Cal(ll n,ll m,ll p){if (m>n) return 0;ll ans = 1;for(int i = 1; i <= m; ++i) ans=ans*Inv(i,p)%p*(n-i+1)%p;return ans%p;} const int manx=3e5+5; struct node{ ll v,next,w; }a[manx*2]; ll head[manx],col[manx]; ll dp[manx]; ll k,ans; void add(ll u ,ll v, ll w){ a[++k].v=v,a[k].w=w,a[k].next=head[u],head[u]=k; } void dfs(ll u,ll pre){ dp[u]=col[u]; ll ma1=0,ma2=0; for(int i=head[u];i;i=a[i].next){ ll v=a[i].v,w=a[i].w; if(v==pre) continue; dfs(v,u); if(ma1<dp[v]+w) ma2=ma1,ma1=dp[v]+w; else if(ma2<dp[v]+w) ma2=dp[v]+w; } dp[u]+=ma1; ans=max(dp[u]+ma2,ans); } int main(){ ll n=read(); for(int i=1;i<=n;i++) col[i]=read(); for(int i=1;i<n;i++){ ll u=read(),v=read(),w=read(); add(u,v,-w); add(v,u,-w); } dfs(1,-1); printf("%lld ",ans); return 0; }
作者:别对自己失望



dp path CodeForces AND

需要 登录 后方可回复, 如果你还没有账号请 注册新账号