Codeforces Round #722 (Div. 2) C. Parsa's Humongous Tree (树形dp)

-
题意:有一颗树,每个结点都有一个取值范围\([L_i,R_i]\),答案为所有相邻点的绝对值之差之和,现在要你确定每个点的值,求最大答案.
-
题解:求相邻点的最大绝对值之差,那么肯定是取两个点的左端点和右端点最优,树形dp板子题.
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int n; PLL pt[N]; ll dp[N][2]; vector<int> edge[N]; ll ans=0; void dfs(int u,int fa){ for(auto w:edge[u]){ if(w==fa) continue; dfs(w,u); dp[u][0]+=max(dp[w][0]+abs(pt[u].fi-pt[w].fi),dp[w][1]+abs(pt[u].fi-pt[w].se)); dp[u][1]+=max(dp[w][0]+abs(pt[u].se-pt[w].fi),dp[w][1]+abs(pt[u].se-pt[w].se)); } } int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int _; cin>>_; while(_--){ cin>>n; rep(i,1,n){ cin>>pt[i].fi>>pt[i].se; } rep(i,1,n) dp[i][0]=dp[i][1]=0; rep(i,1,n) edge[i].clear(); rep(i,1,n-1){ int u,v; cin>>u>>v; edge[u].pb(v); edge[v].pb(u); } dfs(1,0); ll ans=0; rep(i,1,n){ ans=max(ans,dp[i][0]); ans=max(ans,dp[i][1]); } cout<<ans<<'\n'; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号