洛谷 P1351 [NOIP2014 提高组] 联合权值(dp)
传送门
解题思路
先遍历一遍树,求出size[u](节点u的所有相邻节点的点权和),和图中联合权值的最大值。
如何求最大值?
求出每个点相连的点的第一大和第二大点权,相乘后与ans取max。
再求和:
再遍历一遍树,对于每个点u,答案加上w[u]*(size[v]-w[u])。
AC代码
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<iomanip> 5 #include<cmath> 6 using namespace std; 7 const int maxn=200005; 8 const int mod=10007; 9 int n,p[maxn],cnt,w[maxn],fa[maxn]; 10 long long ans,size[maxn]; 11 struct node{ 12 int v,next; 13 }e[maxn*2]; 14 void insert(int u,int v){ 15 cnt++; 16 e[cnt].v=v; 17 e[cnt].next=p[u]; 18 p[u]=cnt; 19 } 20 void dfs(int u,int f){ 21 long long max1=0,max2=0; 22 fa[u]=f; 23 for(int i=p[u];i!=-1;i=e[i].next){ 24 if(e[i].v!=f){ 25 dfs(e[i].v,u); 26 } 27 size[u]+=w[e[i].v]; 28 if(w[e[i].v]>max2) max2=w[e[i].v]; 29 if(max2>max1) swap(max2,max1); 30 } 31 ans=max(ans,max1*max2); 32 } 33 void dfs2(int u){ 34 for(int i=p[u];i!=-1;i=e[i].next){ 35 if(e[i].v!=fa[u]) dfs2(e[i].v); 36 ans+=w[u]*(size[e[i].v]-w[u]); 37 } 38 } 39 int main(){ 40 memset(p,-1,sizeof(p)); 41 cin>>n; 42 for(int i=1;i<n;i++){ 43 int u,v; 44 scanf("%d%d",&u,&v); 45 insert(u,v); 46 insert(v,u); 47 } 48 for(int i=1;i<=n;i++) scanf("%d",&w[i]); 49 dfs(1,-1); 50 cout<<ans<<" "; 51 ans=0; 52 dfs2(1); 53 cout<<ans%mod; 54 return 0; 55 }
作者:尹昱钦
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· 语音处理 开源项目 EchoSharp
· 《HelloGitHub》第 106 期
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 使用 Dify + LLM 构建精确任务处理应用
2020-02-22 洛谷 P1880 [NOI1995]石子合并(区间dp,断环为链)
2020-02-22 洛谷 P1901 发射站(单调栈)