该网站在工信部的icp ip地址,宝安在深圳算什么档次,石家庄最新情况,网站建设策划实施要素有哪些CF 1529C Parsa’s Humongous Tree
题意#xff1a;
给你一颗n个点#xff0c;n-1个边的树#xff0c;每个点的点权为一个区间值#xff0c;树的值为边权和。 边权为该边的两个端点的点权差的绝对值的和 问树的值最大是多少#xff1f;
题解#xff1a;
这个题给的点…CF 1529C Parsa’s Humongous Tree
题意
给你一颗n个点n-1个边的树每个点的点权为一个区间值树的值为边权和。 边权为该边的两个端点的点权差的绝对值的和 问树的值最大是多少
题解
这个题给的点权是一个范围值范围值的话如何找打最佳值结合题目给的边权计算方法两个点的权值差的绝对值如果一个点权是[a,b]另一个是[c,d]那边权的最大值要么是abs(a-d),要么是abs(b-c)也就是端点之间的差这样每个点的点权就是二选一我们可以用树形dp来解答 dp[u][0/1]:表示以u为根节点0表示u的点权选择左端点1表示选择右端点 可以得到转移方程v是u的儿子
dp[u][0]max(abs(w[u][0]-w[v][0])dp[v][0],abs(w[u][0]-w[v][1])dp[v][1]);
dp[u][1]max(abs(w[u][1]-w[v][0])dp[v][0],abs(w[u][1]-w[v][1])dp[v][1]);;不难明白就是将u的左右和v的左右都尝试分别取最大 最终答案是max(dp[u][0],dp[u][1])
代码
#includebits/stdc.h
#define debug(a,b) printf(%s %d\n,a,b);
typedef long long ll;
using namespace std;inline int read(){int s0,w1;char chgetchar();while(ch0||ch9){if(ch-)w-1;chgetchar();}while(ch0ch9) ss*10ch-0,chgetchar();//s(s3)(s1)(ch^48);return s*w;
}
const int maxn1e59;
ll dp[maxn][3];
ll w[maxn][3];
vectorintvec[maxn];
void dfs(int u,int fa){for(int i0;ivec[u].size();i){int vvec[u][i];if(vfa)continue;dfs(v,u);dp[u][0]max(abs(w[u][0]-w[v][0])dp[v][0],abs(w[u][0]-w[v][1])dp[v][1]);dp[u][1]max(abs(w[u][1]-w[v][0])dp[v][0],abs(w[u][1]-w[v][1])dp[v][1]);;}
}
int main()
{int t;cint;while(t--){int n;scanf(%d,n);memset(dp,0,sizeof(dp));memset(w,0,sizeof(w));for(int i1;in;i){scanf(%d%d,w[i][0],w[i][1]);//分别表示左端点和右端点 }for(int i1;in;i){int u,v;scanf(%d%d,u,v);vec[u].push_back(v);vec[v].push_back(u);}dfs(1,-1);coutmax(dp[1][0],dp[1][1])endl;for(int i1;in;i)vec[i].clear();}return 0;
}