联合权值

题目大意

给你一个图,有\(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. nyoj--114--某种序列(滚动数组)

    某种序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 数列A满足An = An-1 + An-2 + An-3, n >= 3  编写程序,给定A0, A1 和 ...

  2. NEU2016年一月月赛回顾

    月赛传送门 http://acm.neu.edu.cn/hustoj/contest.php?cid=1066 月赛已经结束十天了...才把题目补完真是大失误... 茅巨巨四天前就补完了,,,总结写得 ...

  3. ROS-多机通信

    前言:一定要在同一路由的局域网下进行,就是两台电脑的ip要像这样:192.168.191.4和192.168.191.8,只有最后一位不同,这样就能ping通了,否则ping不同. 一.查看ip和主机 ...

  4. POJ 3185 DFS

    好像可以用高斯消元??? 但是用搜索写 这题就很水了... // by SiriusRen #include <bitset> #include <cstdio> using ...

  5. linux 命令cp拷贝

    linux复制指定目录下的全部文件到另一个目录中复制指定目录下的全部文件到另一个目录中文件及目录的复制是经常要用到的.linux下进行复制的命令为cp.假设复制源目录 为 dir1 ,目标目录为dir ...

  6. (转)Django学习之 第四章:Django模板系统

    前面的章节我们看到如何在视图中返回HTML,但是HTML是硬编码在Python代码中的 这会导致几个问题: 1.显然,任何页面的改动会牵扯到Python代码的改动 网站的设计改动会比Python代码改 ...

  7. WebApp开发技巧大全

    1.开发成本较低使用web开发技术就可以轻松的完成web app的开发 2.升级较简单升级不需要通知用户,在服务端更新文件即可,用户完全没有感觉 3.维护比较轻松和一般的web一样,维护比较简单,它其 ...

  8. luoguP4238 【模板】多项式求逆 NTT

    Code: #include <bits/stdc++.h> #define N 1000010 #define mod 998244353 #define setIO(s) freope ...

  9. pythone 学习笔记(粗略)

    文档目录 概述 安装 基本语法 数据结构 4.1 数字和字符串类型 4.2 元祖 4.3 列表 4.4 字典 流程语句 5.1 分支结构 5.2 逻辑运算符(if) 5.3 循环 5.3.1 for ...

  10. BZOJ 4026 dC Loves Number Theory (主席树+数论+欧拉函数)

    题目大意:给你一个序列,求出指定区间的(l<=i<=r) mod 1000777 的值 还复习了欧拉函数以及线性筛逆元 考虑欧拉函数的的性质,(l<=i<=r),等价于 (p[ ...