『题解』洛谷P1351 联合权值
Portal
Portal1: Luogu
Portal2: LibreOJ
Description
无向连通图\(\mathrm G\)有\(n\)个点,\(n - 1\)条边。点从\(1\)到\(n\)依次编号,编号为\(i\)的点的权值为\(W_i\) ,每条边的长度均为\(1\)。图上两点\((u, v)\)的距离定义为\(u\)点到\(v\)点的最短距离。对于图\(\mathrm G\)上的点对\((u, v)\),若它们的距离为\(2\),则它们之间会产生\(W_u \times W_v\)的联合权值。
请问图\(\mathrm G\)上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?
Input
第一行包含\(1\)个整数\(n\)。
接下来\(n - 1\)行,每行包含2个用空格隔开的正整数\(u, v\),表示编号为\(u\)和编号为\(v\)的点之间有边相连。
最后\(1\)行,包含\(n\)个正整数,每两个正整数之间用一个空格隔开,其中第\(i\)个整数表示图\(\mathrm G\)上编号为i的点的权值为\(W_i\)。
Output
输出共\(1\)行,包含\(2\)个整数,之间用一个空格隔开,依次为图\(\mathrm G\)上联合权值的最大值和所有联合权值之和。由于所有联合权值之和可能很大,输出它时要对\(10007\)取余。
Sample Input
5
1 2
2 3
3 4
4 5
1 5 2 3 10
Sample Output
20 74
Solution
我们先看一下题目:无向连通图\(\mathrm G\)有\(n\)个点,\(n - 1\)条边。
不难发现题目给出的是一颗树。
我们看一个例子:

这个图的联合权值和为\(W_2 \times W_3 + W_4 \times W_5 + W_4 \times W_6 + W_5 \times W_6 + W_7 \times W_8\)。

不难发现,我们求的是对于每一棵子树的非根节点的所有子结点两两相乘的权值和。但是我们对每一棵子树都遍历一遍显然要超时。我们可以找到如下性质:
\((a + b) ^ 2 = a ^ 2 + b ^ 2 + 2ab \\\ (a + b + c) ^ 2 = a ^ 2 + b ^ 2 + c ^ 2 + 2ab+ 2ac + 2bc \\\ (a + b + c + d) = a ^ 2 + b ^ 2 + c ^ 2 + d ^ 2 + 2ab+ 2ac + 2ad + 2bc + 2bd + 2cd \\\ \cdots \cdots\)
我们要求的就是平方项后面的一半。就是 \(\texttt{和的平方} - \texttt{平方的和}\) 。
统计最大值是只需要找出最大的两项,然后相乘就可以了。
这样就这道题就解决了。
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f, MAXN = 400005, MAXM = 200005, mod = 10007;
struct EDGE {
int to, nxt;
} edge[MAXN];
int n, u, v, cnt, w[MAXM], head[MAXN];
inline void addedge(int u, int v) {
edge[++cnt].to = v; edge[cnt].nxt = head[u]; head[u] = cnt;
}
int main() {
scanf("%d", &n);
memset(head, -1, sizeof(head));
for (int i = 1; i < n; i++) {
scanf("%d%d", &u, &v);
addedge(u, v); addedge(v, u);//加边
}
for (int i = 1; i <= n; i++)
scanf("%d", &w[i]);
LL Max = -INF, ans = 0;
for (int i = 1; i <= n; i++) {
LL Max1 = -INF, Max2 = -INF, tot1 = 0, tot2 = 0;//Max1表示最大的权值,Max2表示第二大的权值,tot1表示和的平方,tot2表示平方的和
for (int j = head[i]; ~j; j = edge[j].nxt) {//遍历每一个点
if (w[edge[j].to] > Max1) {
Max2 = Max1;
Max1 = w[edge[j].to];
} else
if (w[edge[j].to] > Max2 && w[edge[j].to] <= Max1) Max2 = w[edge[j].to];//找两个最大的
tot1 += w[edge[j].to]; tot2 = (tot2 + w[edge[j].to] * w[edge[j].to]) % mod;//累计当前点的权值
}
tot1 = (tot1 % mod * tot1 % mod) % mod;//和的平方
ans = (ans + tot1 - tot2 + mod) % mod;//累加答案
Max = max(Max, Max1 * Max2);//找最大权值
}
printf("%lld %lld\n", Max, ans);
return 0;
}
Attachment
测试数据下载:https://www.lanzous.com/i5q1vdg
『题解』洛谷P1351 联合权值的更多相关文章
- 洛谷 P1351 联合权值 题解
P1351 联合权值 题目描述 无向连通图 \(G\) 有 \(n\) 个点,\(n-1\) 条边.点从 \(1\) 到 \(n\) 依次编号,编号为 \(i\) 的点的权值为 \(W_i\),每条 ...
- [NOIP2014] 提高组 洛谷P1351 联合权值
题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...
- 洛谷 P1351 联合权值
题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...
- 洛谷——P1351 联合权值
https://www.luogu.org/problem/show?pid=1351 题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i , ...
- 洛谷P1351 联合权值(树形dp)
题意 题目链接 Sol 一道很简单的树形dp,然而被我写的这么长 分别记录下距离为\(1/2\)的点数,权值和,最大值.以及相邻儿子之间的贡献. 树形dp一波.. #include<bits/s ...
- 洛谷 P1351 联合权值 —— 树形DP
题目:https://www.luogu.org/problemnew/show/P1351 树形DP,别忘了子树之间的情况(拐一下距离为2). 代码如下: #include<iostream& ...
- 洛谷P1351 联合权值
\(\Large\textbf{Description:}\) \(\large一棵树,父子之间距离为1,求距离为2的两点点权之积的最大值与和.\) \(\Large\textbf{Solution: ...
- 『题解』洛谷P1063 能量项链
原文地址 Problem Portal Portal1:Luogu Portal2:LibreOJ Portal3:Vijos Description 在\(Mars\)星球上,每个\(Mars\)人 ...
- 『题解』洛谷P1993 小K的农场
更好的阅读体验 Portal Portal1: Luogu Description 小\(K\)在\(\mathrm MC\)里面建立很多很多的农场,总共\(n\)个,以至于他自己都忘记了每个农场中种 ...
随机推荐
- vue父子组件钩子函数的执行顺序
加载渲染过程 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount-& ...
- asp.net开源流程引擎API开发调用接口大全-工作流引擎设计
关键词: 工作流引擎 BPM系统 接口调用 工作流快速开发平台 工作流流设计 业务流程管理 asp.net 开源工作流 一.程序调用开发接口二. 接口说明 所谓的驰骋工作流引擎的接口,在B ...
- springboot 自定义LocaleResolver切换语言
springboot 自定义LocaleResolver切换语言 我们在做项目的时候,往往有很多项目需要根据用户的需要来切换不同的语言,使用国际化就可以轻松解决. 我们可以自定义springboor中 ...
- WCE-hash注入工具使用
wce的使用说明如下 参数解释:-l 列出登录的会话和NTLM凭据(默认值)-s 修改当前登录会话的NTLM凭据 参数:<用户名>:<域 ...
- PHP 插入排序 -- 折半查找
1. 折半查找 -- Binary Insertion Sort 时间复杂度 : O(n^2) 适用条件 : 相对直接插入排序,减少了数值的比较次数.适用于需要排序的数码比较少的情况. <?p ...
- JavaScript 编译器-Babel
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行.这意味着,你可以现在就用ES6.ES7编写程序,而不用担心现有环境是否支持. 一.全局安装babel工具 在保证n ...
- 为什么要学3D建模呢?你看中的肯定是这几点
游戏行业的大环境 互联网的形态一直以来都是2D模式的,但是随着3D技术的不断进步,在未来的5年时间里,将会有越来越多的互联网应用以3D的方式呈现给用户,包括网络视讯.电子阅读.虚拟社区.网络游戏.电子 ...
- 前端深入之css篇丨初探【transform】,手把手带你实现1024程序员节动画
写在前面 马上就2020年了,不知道小伙伴们今年学习了css3动画了吗? 说起来css动画是一个很尬的事,一方面因为公司用css动画比较少,另一方面大部分开发者习惯了用JavaScript来做动画,所 ...
- PHP代码审计基础-中级篇
初级篇更多是对那些已有的版本漏洞分析,存在安全问题的函数进行讲解,中级篇更多是针对用户输入对漏洞进行利用 中级篇更多是考虑由用户输入导致的安全问题. 预备工具首先要有php本地环境可以调试代码 总结就 ...
- 2.2 C语言_实现数据容器vector(排序功能)
上一节我们说到我们己经实现了一般Vector可以做到的自动扩充,告诉随机存取,那么现在我们需要完成vector的一个排序的功能. 排序算法我们网上一百度哇~~!很常见的就有8大排序算法: 1.选择排序 ...