luogu 1351 联合权值
联合权值
题目大意
给你一个图,有\(n-1\)条边,距离均为\(1\),每距离为\(2\)的两个点的联合权值为\(W_u \times W_v\),求联合权值的最大值和联合权值总和。
solution
70pts
这道题稍微看一下就想到可以枚举一个点,然后对于每个点所相连的点到另一个所相连的点的距离一定为\(2\),所以我们就可以暴力枚举这一个点,然后进行加和。这样我们就得到了70分的做法。
// 70pts
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n;
const int mod = 10007;
struct edge {
int next,to;
} e[400000];
int head[400001],tot,val[200001],maxn=-0x7fffffff,ans,fa[200001];
void add(int x,int y) {
e[++tot].next = head[x];
head[x] = tot;
e[tot].to = y;
}
void dfs_bgn(int x,int f) {
fa[x]=f;
for(int i=head[x]; i; i=e[i].next) {
int v=e[i].to;
if(v!=f)
dfs_bgn(v,x);
}
return ;
}
void dfs(int x) {
for(int i=head[x]; i; i=e[i].next) {
int v=e[i].to;
if(v!=fa[x]) {
int k=fa[x];
if(k!=0) {
ans+=((val[k]%mod)*(val[v]%mod))%mod;
ans%=mod;
ans+=((val[k]%mod)*(val[v]%mod))%mod;
ans%=mod;
maxn=max(maxn,val[k]*val[v]);
}
dfs(v);
}
}
for(int i=head[x]; i; i=e[i].next)
for(int j=head[x]; j; j=e[j].next) {
int k=e[i].to,v=e[j].to;
if(k!=v && k!=fa[x] && v!=fa[x]) {
ans+=((val[k]%mod)*(val[v]%mod))%mod;
ans%=mod;
maxn=max(maxn,val[k]*val[v]);
}
}
}
int main() {
scanf("%d",&n);
for(int i=1; i<n; i++) {
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
for(int i=1; i<=n; i++)scanf("%d",&val[i]);
dfs_bgn(1,0);
dfs(1);
printf("%d %d",maxn,ans);
return 0;
}
100pts
因为现在没考试,所以思想比较懈怠,就没有相处100pts的做法。
100pts的做法就是加了一步小优化,将我的n方枚举转变为线性。
线性做法是这样的,枚举到一个点,那么它的一个相邻点必定会乘以其他的点,所以这就是一个乘法分配律。
既然这样,我们就好说了。我们求出每个点相邻点的总和,然后再根据乘法分配律对答案进行更新。
那么最大值怎么办呢?最大值的话可以仔细想想,因为最大值就是一个点所相连的最大乘以次大,所以我们再枚举这个点周边点的时候维护一下就行了。
//100pts
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n;
const long long mod = 10007;
struct edge {
int next,to;
} e[400000];
int head[400001],tot,fa[200001];
long long val[200001],maxn=-0x7fffffff,ans;
void add(int x,int y) {
e[++tot].next = head[x];
head[x] = tot;
e[tot].to = y;
}
void dfs_bgn(int x,int f) {
fa[x]=f;
for(int i=head[x]; i; i=e[i].next) {
int v=e[i].to;
if(v!=f)
dfs_bgn(v,x);
}
return;
}
void dfs(int x) {
long long max1=0,max2=0,sum=0;
for(int i=head[x]; i; i=e[i].next) {
int v=e[i].to;
if(v!=fa[x]) dfs(v);
if(max1<val[v])max2=max1,max1=val[v];
else if(max1==val[v])max2=max1;
else if(max1>val[v] && max2<val[v]) max2=val[v];
sum+=val[v];
}
maxn=max(maxn,max1*max2);
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
ans=(ans+(val[v]%mod)*(sum-val[v]%mod))%mod;
ans%=mod;
}
}
int main() {
scanf("%d",&n);
for(int i=1; i<n; i++) {
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
for(int i=1; i<=n; i++)scanf("%lld",&val[i]),val[i]%=mod;
dfs_bgn(1,0);
dfs(1);
printf("%lld %lld",maxn,ans);
return 0;
}
luogu 1351 联合权值的更多相关文章
- luogu P1351 联合权值
题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...
- [NOIp2014] luogu P1351 联合权值
哎我博 4 了. 题目描述 无向连通图 GGG 有 nnn 个点,n−1n−1n−1 条边.点从 111 到 nnn 依次编号,编号为 iii 的点的权值为 WiW_iWi,每条边的长度均为 111 ...
- Luogu P1351 联合权值 题解
这是一个不错的树形结构的题,由于本蒟蒻不会推什么神奇的公式其实是懒得推...,所以很愉快的发现其实只需要两个点之间的关系为祖父和儿子.或者是兄弟即可. 然后问题就变得很简单了,只需要做一个正常的DFS ...
- 【luogu P1351 联合权值】 题解
题目链接:https://www.luogu.org/problemnew/show/P1351 做了些提高组的题,不得不说虽然NOIP考察的知识点虽然基本上都学过,但是做起题来还是需要动脑子的. 题 ...
- 洛谷 1351 联合权值——树形dp
题目:https://www.luogu.org/problemnew/show/P1351 对拍了一下,才发现自己漏掉了那种拐弯的情况. #include<iostream> #incl ...
- Luogu 1351 NOIP 2014 联合权值(贪心,计数原理)
Luogu 1351 NOIP 2014 联合权值(贪心,计数原理) Description 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi, ...
- [Luogu 1351] NOIP2014 联合权值
[Luogu 1351] NOIP2014 联合权值 存图,对于每一个点 \(u\),遍历它的所有邻接点.以 \(u\) 为中转点的点对中,\((x,y)\) 的联合权值 \(w_x \cdot w_ ...
- 【NOIP2014提高组】联合权值
https://www.luogu.org/problem/show?pid=1351 既然是一棵树,就先转化成有根树.有根树上距离为2的点对,路径可能长下面这样: 枚举路径上的中间点X. 第一种情况 ...
- 洛谷——P1351 联合权值
https://www.luogu.org/problem/show?pid=1351 题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i , ...
随机推荐
- 一个Python项目的创建架构
要进行Python项目的编写,很多人刚开始一筹莫展,不知道该如何去构建一个项目,现在粗略的描述一下一个项目的创建过程,供大家参考了解一下: 大家可以先忽略其中创建的函数 ,每个包的含义都有定义,大家可 ...
- Noip蒟蒻专用模板
目录 模板 数论 线性筛素数 线性筛欧拉 裴蜀定理 卢卡斯定理 矩阵快速幂 逆元 高斯消元 图论 割点 最小生成树 倍增 SPFA 负环 堆优化迪杰斯特拉 匈牙利 数据结构 树状数组 ST表 线段树 ...
- 网易NAPM Andorid SDK实现原理--转
原文地址:https://neyoufan.github.io/2017/03/10/android/NAPM%20Android%20SDK/ NAPM 是网易的应用性能管理平台,采用非侵入的方式获 ...
- 压力测试工具 Tinyget
Tinyget 压力测试工具使用方法为:命令行切换到工具所在路径下,然后输入压力命令.如:tinyget -srv:localhost -uri:/FeaturedProdu1cts.aspx -th ...
- Java基础——环境变量(PATH)和类变量(CLASSPATH)
一.环境变量(PATH) 科普下,环境变量不是java的知识,是windows系统的环境变量. 下面请看怎么查看和修改windows的环境变量 在“我的电脑”右键属性进入后 点击“高级系统设置”(如下 ...
- jQuery应用实例3:鼠标经过显示离开隐藏
效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- JAVA-mysql读写分离插件介绍
kingshard是一个由Go开发高性能MySQL Proxy项目,kingshard在满足基本的读写分离的功能上,致力于简化MySQL分库分表操作:能够让DBA通过kingshard轻松平滑地实现M ...
- ASP.NET 页面缓存OutputCache用法实例(附ab压力测试对比图)
本文主要介绍Web窗体页面中的使用方法,MVC中使用方法,大家自行百度. 一.简单一行指令即可实现 <%@ OutputCache VaryByParam=" %> 这样整个页面 ...
- NSPort与NSRunloop的关系是流与消息调度的关系
NSPort与NSRunloop的关系是流与消息调度的关系. NSPort 将流插入到消息调度队列: 相当于 Socket将流插入到应用一样 - (void)launchThread { NSPort ...
- C语言基础 (4) 原码反码补码与数据类型
1.回顾 使用gcc编译代码 gcc hello.c -o hello windows下编译代码 C语言编译步骤: 预处理(头文件展开,干掉注释) gcc -E hello.c -o hello.i ...