联合权值

题目大意

给你一个图,有\(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 联合权值的更多相关文章

  1. luogu P1351 联合权值

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  2. [NOIp2014] luogu P1351 联合权值

    哎我博 4 了. 题目描述 无向连通图 GGG 有 nnn 个点,n−1n−1n−1 条边.点从 111 到 nnn 依次编号,编号为 iii 的点的权值为 WiW_iWi​,每条边的长度均为 111 ...

  3. Luogu P1351 联合权值 题解

    这是一个不错的树形结构的题,由于本蒟蒻不会推什么神奇的公式其实是懒得推...,所以很愉快的发现其实只需要两个点之间的关系为祖父和儿子.或者是兄弟即可. 然后问题就变得很简单了,只需要做一个正常的DFS ...

  4. 【luogu P1351 联合权值】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1351 做了些提高组的题,不得不说虽然NOIP考察的知识点虽然基本上都学过,但是做起题来还是需要动脑子的. 题 ...

  5. 洛谷 1351 联合权值——树形dp

    题目:https://www.luogu.org/problemnew/show/P1351 对拍了一下,才发现自己漏掉了那种拐弯的情况. #include<iostream> #incl ...

  6. Luogu 1351 NOIP 2014 联合权值(贪心,计数原理)

    Luogu 1351 NOIP 2014 联合权值(贪心,计数原理) Description 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi, ...

  7. [Luogu 1351] NOIP2014 联合权值

    [Luogu 1351] NOIP2014 联合权值 存图,对于每一个点 \(u\),遍历它的所有邻接点.以 \(u\) 为中转点的点对中,\((x,y)\) 的联合权值 \(w_x \cdot w_ ...

  8. 【NOIP2014提高组】联合权值

    https://www.luogu.org/problem/show?pid=1351 既然是一棵树,就先转化成有根树.有根树上距离为2的点对,路径可能长下面这样: 枚举路径上的中间点X. 第一种情况 ...

  9. 洛谷——P1351 联合权值

    https://www.luogu.org/problem/show?pid=1351 题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i , ...

随机推荐

  1. weblogic管理脚本

    start.sh Java代码  #!/usr/bin/bash # # start.sh # @auth: zhoulin@lianchuang.com # SERVER_STATUS () { s ...

  2. Vmware 安装虚拟工具 (二)

    打开虚拟机,以root超级用户登陆,菜单栏选择虚拟机,install安装虚拟机 拷贝虚拟工具到 在根目录下建立文件夹,并将工具拷贝到该文件夹,例如vmtool 打开终端,进入该目录开始安装 如图,进入 ...

  3. xBIM 学习与应用系列目录

        xBIM 实战04 在WinForm窗体中实现IFC模型的加载与浏览   xBIM 实战03 使用WPF技术实现IFC模型的加载与浏览   xBIM 实战02 在浏览器中加载IFC模型文件并设 ...

  4. PHP分页组件:Paginator

    安装 composer require "jasongrimes/paginator:~1.0" 使用 <?php require '../vendor/autoload.p ...

  5. FloatActionButton弹出菜单

    浮动按钮的弹出菜单动画 将几个按钮重叠摆放,使用ValueAnimator更新按钮的坐标实现. 布局 <FrameLayout android:layout_width="match_ ...

  6. ContentType 列表

    CONTENTTYPE是html里面都带有的,ASP只是设置当前的CONTENTTYPE在浏览器中,ContentType一般指定当前的文档内容,浏览器即根据相应的MIME及Content-Type映 ...

  7. 腾讯测试工程师:你以为会打LOL就能做测试了?

    周日参加完公司团建,回家路上拼到一个IT界的老司机,他和几个朋友组件团队承接开发项目,知道我是做测试的,问了我一个问题: “你们大公司的测试都做什么?” “测试应该不好模仿吧?” 刚开始我也不清楚他的 ...

  8. MongoDB_安装

    windows安装MongoDB 官网下载地址:https://www.mongodb.com/download-center?jmp=nav#community (1)如图点击DOWNLOAD进行下 ...

  9. LeetCode Golang 5. 最长回文子串

    5. 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab&quo ...

  10. spring的JdbcTemplate

    一.首先配置JdbcTemplate: 要使用Jdbctemplate 对象来完成jdbc 操作.通常情况下,有三种种方式得到JdbcTemplate 对象.       第一种方式:我们可以在自己定 ...