【树型dp】联合权值
作者:@魔幻世界魔幻人生
本文为作者原创,转载请注明出处:https://www.cnblogs.com/subtlemaple/p/16424843.html
请问图 G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?
输入格式 第一行包含 1 个整数 n。
接下来 n−1 行,每行包含 2 个用空格隔开的正整数 u,v,表示编号为 u 和编号为 v 的点之间有边相连。
最后 1 行,包含 n 个正整数,每两个正整数之间用一个空格隔开,其中第 i 个整数表示图 G 上编号为 i 的点的权值为 Wi。
输出格式 输出共 1 行,包含 2 个整数,之间用一个空格隔开,依次为图 G 上联合权值的最大值和所有联合权值之和。由于所有联合权值之和可能很大,输出它时要对10007取余。
重要结论
2ab = (a+b)^{2} - (a^2+b^2)
2ab+2ac+2bc=(a+b+c)^2-(a^2+b^2+c^2)
推论:对于一个集合中的数,二倍两数之积的组合等于所有元素的完全平方和减去其平方之和
此题注意:有序点对(u,v) 和 (v,u) 是不同的点对
代码加注释:
//联合权值
//
/*
一颗无根无向树上每条边距离都是1,每个点i都有一个权值w[i],
定义两点距离为其最短距离,
若一个有序点对(i,j)距离是2,则它们有联合权值 w[i]*w[j]
求整颗图上最大的联合权值,以及所有联合权值之和
*/
/*
问题一:
我们注意到若以一个点u为根,
则它的任意两个子节点距离都是2,可以形成联合权值 ,
且u和它的祖父也能形成联合权值
那么只需要以任一点u为根节点进行dfs,
找到 u的子节点权值最大的和次大的,
然后用其乘积刷新当前最大权值 ,
再用u和它祖父的乘积刷新最大权值
问题二:
注意点对有序,所以找到所有联合权值和之后要乘2
那么假如两个符合要求的点w分别为a和b,那么2ab就对答案有贡献,
而我们知道任意几个数的完全平方和减去它们的平方之和,就是它们两两组合之积的二倍
那问题就迎刃而解了,注意只对联合权值总和取模,
对最大值不做处理
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define il inline
using namespace std;
const int maxn=2e5+10;
const int mod=10007;
int h[maxn],cnt;
struct edge{
int to,nxt;
}e[maxn<<1];
il void addedge(int x,int y)
{
cnt++;
e[cnt].to=y; e[cnt].nxt=h[x]; h[x]=cnt; return;
}
int w[maxn];
int n;
int ans_1,ans_2;
void dfs(int u,int fa,int gf)
{
int sum=0,squ=0,maxx=0,mavv=0;
for(int i=h[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa) continue;
sum=(sum+w[v])%mod;
squ=(squ+w[v]*w[v]%mod)%mod;
if(w[v]>maxx)
{
mavv=maxx; maxx=w[v];
}
else//注意是else
if(w[v]>mavv) mavv=w[v];
dfs(v,u,fa);
}
ans_1=max(ans_1,max(mavv*maxx,w[u]*w[gf]));
//联合权值最大
ans_2=(ans_2+sum*sum%mod-squ+mod+mod)%mod;
//计算子节点之间的联合权值之和
ans_2=(ans_2+w[u]*w[gf]*2%mod)%mod;
//别忘了还有u和爷爷的联合权值没加
}
int main()
{
//freopen("data.in","r",stdin);
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
addedge(u,v);
addedge(v,u);
}
for(int i=1;i<=n;i++)
{
cin>>w[i];
}
dfs(1,0,0);//u,父亲,祖父
cout<<ans_1<<" "<<ans_2;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】