还是先看题吧:

试题描述
 无向连通图 G 有 n 个点,n-1 条边。点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi ,每条边的长度均为 1。图上两点(u, v)的距离定义为 u 点到 v 点的最短距离。对于图 G 上的点对(u, v),若它们的距离为 2,则它们之间会产生Wu * Wv 的联合权值。请问图 G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?
输入
第一行包含 1 个整数 n。
接下来 n-1 行,每行包含 2 个用空格隔开的正整数 u、v,表示编号为 u 和编号为 v 的点之间有边相连。
最后 1 行,包含 n 个正整数,每两个正整数之间用一个空格隔开,其中第 i 个整数表示图 G 上编号为 i 的点的权值为 Wi。 
输出
输出共 1 行,包含 2 个整数,之间用一个空格隔开,依次为图 G 上联合权值的最大值和所有联合权值之和。由 于 所 有 联 合 权 值 之 和 可 能 很 大 , 输 出 它 时 要 对 10007 取 余 。
输入示例
5
1 2
2 3
3 4
4 5
1 5 2 3 10 
输出示例
20 74
其他说明
样例说明:距离为 2 的有序点对有(1,3)、(2,4)、(3,1)、(3,5)、(4,2)、(5,3)。其联合权值分别为 2、15、2、20、15、20。其中最大的是 20,总和为 74。
数据范围:对于 100% 的数据,1 < n ≤ 200,000,0 < Wi ≤ 10,000。 

十分郁闷,只过了7个点,剩下3个点莫名其妙在第二个数值上WA了。

还是先说思路吧,首先看到n的范围,肯定就是用邻接表存了(注意无向图要正着反着各存一次),还有题目中所说无相连通图有n个节点,n-1条边,说明这是一棵树。然后就开始求解了,第一问:可以依次枚举,但是这样太慢了。我们可以针对每一个节点,通过邻接表来找到它的所有邻居,然后依次判断他们的点权,对于每一个节点维护两个值,该点邻居中点权的第一大和第二大,扫过一遍之后,我们只需找哪一个点第一大与第二大乘积最大即可求出第一问。下面是第二问:看到第二问大家第一反应肯定是找到该点的所有邻居,然后每两个点一次算一遍点权的乘积,累加起来就是结果,第二反应就是这样是O(n^2)的复杂度,不用想肯定超时,第三反应就是设法想到O(N)或O(N log N)的算法。然后就开始想:对于一个节点p,他的邻居a,b,c,d,e……我们需要算ab+ac+ad+……bc+bd……这样能不能用数学公式来实现呢?由于最近刷学校留的暑假作业(初高中数学衔接读本),里面正好有一个章节就在讲因式分解,其中公式背的很6:(a+b)^2=a^2+b^2+2ab,(a+b+c)^2=a^2+b^2+c^2+2*(ab+ac+bc)……然后就立刻联想到其中的ab+ac+bc不就正是我要求的吗?知道这样,我们针对每一个点,只需把这个点的邻居的平方和以及和的平方维护即可,到时候一相减即可算出,时间复杂度O(N)。

下面是代码:

 #include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<conio.h>
using namespace std;
const int maxn=+;
int n,u[maxn],v[maxn],w[maxn],first[*maxn],next[*maxn],a,b,MAX,lMAX,ans1,sum1,sum2,ans2;
int read()
{
int f=,x=;
char ch=getchar();
if(ch=='-') f=-;
while(ch<''||ch>'')
{
if(ch=='-')f=-;
ch=getchar();
}
while(ch>=''&& ch<='') { x=x*+ch-''; ch=getchar(); }
return x*f;
}
void addEdge(int i,int a,int b)//加边
{
u[i]=a;v[i]=b;
next[i]=first[a];
first[a]=i;
}
int main()
{
memset(first,-,sizeof(first));
n=read();
for(int i=;i<n-;i++)
{
a=read();b=read();
addEdge(*i,a,b);
addEdge(*i+,b,a);
}
for(int i=;i<=n;i++)w[i]=read();
for(int i=;i<=n;i++)
{
sum1=sum2=MAX=;
lMAX=-;
for(int j=first[i];j!=-;j=next[j])
{
if(w[v[j]]>lMAX)//维护最大值和次最大值
{
if(w[v[j]]>MAX)MAX=w[v[j]];
else lMAX=w[v[j]];
}
sum1=(sum1+w[v[j]])%;//维护邻居中点权的和
sum2=(sum2+(w[v[j]]%*w[v[j]]%)%)%;//维护邻居中点权的平方和
}
ans1=max(ans1,MAX*lMAX);
ans2=(ans2+(((sum1*sum1)%-sum2))+)%; //套公式
}
printf("%d %d",ans1,ans2);
return ;
}

其中还有一个注意事项,就是代码55行中加了一个10007,因为这些都是取模运算,并且其中还有相减的运算,所以很有可能算成负数,因此我们需要加上一个10007这样就能解决出负数的问题了(其实钱老师在讲食物链的时候提到过),以后一定要牢记这些经验教训。

NOIP2014提高组第二题联合权值的更多相关文章

  1. 【前缀和】【前缀MAX】洛谷 P1351 NOIP2014提高组 day1 T2 联合权值

    不难发现,树中与某个点距离为2的点只可能是它的父亲的父亲.儿子的儿子 或者 兄弟,分类讨论一下即可. 只有对于兄弟我们不能暴力搞,维护一下每个节点的所有儿子的前缀和.前缀MAX就行了. #includ ...

  2. 「NOIP2014」「Codevs3728」 联合权值(乱搞

    3728 联合权值 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold   题目描述 Description 输入描述 Input Description 输出描述 Ou ...

  3. 【枚举】Vijos P1496 火柴棒等式 (NOIP2008提高组第二题)

    题目链接: https://vijos.org/p/1496 题目大意: 给你n(n<24)根火柴棍,你可以拼出多少个形如“A+B=C”的等式?("+"和"=&qu ...

  4. 【动态规划】Vijos P1313 金明的预算方案(NOIP2006提高组第二题)

    题目链接: https://vijos.org/p/1313 题目大意: m(m<=32000)金钱,n(n<=60)个物品,花费vi,价值vi*ci,每个物品可能有不超过2个附件,附件没 ...

  5. NOIP 2014 T2 联合权值 DFS

    背景 NOIP2014提高组第二题 描述 无向连通图G有n个点,n-1条边.点从1到n依次编号,编号为i的点的权值为Wi ,每条边的长度均为1.图上两点(u, v)的距离定义为u点到v点的最短距离.对 ...

  6. 【学术篇】luogu1351 [NOIP2014提高组] 联合权值

    一道提高组的题..... 传送门:题目在这里.... 现在都懒得更自己的blog了,怕是太颓废了_ (:з」∠) _ 好久没做题了,手都生了.(好吧其实是做题方面手太生了) 这题我都不想讲了,把代码一 ...

  7. Noip2014 提高组 T2 联合权值 连通图+技巧

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

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

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

  9. [NOIP2014] 提高组 洛谷P1351 联合权值

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

随机推荐

  1. 【转】CSS

    css概念 http://www.cnblogs.com/moveofgod/archive/2012/09/18/2691101.html css八大功能 http://developer.51ct ...

  2. Sql Server中三种字符串合并方法的性能比较

    文章来自:博客园-DotNet菜园 最近正在处理一个合并字符吕的存储过程,在一个测试系统的开发中,要使用到字符串合并功能,直接在Sql中做.示例:有表內容﹕名称  內容1     abc1      ...

  3. H264中的MapUnits

    1 MapUnits 在FMO(Flexible Macroblock ordering)时,从宏块到条带组的映射是以MapUnits为基本单位,MapUnits可能为宏块,也可能是上下两个宏块(见下 ...

  4. intellig idea 快捷键

    可以在设置中更改为 eclipse 风格的快捷键. 默认 按住 ctlr + 左键,会调整到对应的声明处, 如果有实现类,eclipse中给予了选择. 在idea 中如果想直接调整到实现类,那么采用快 ...

  5. My Sql多表操作(转载)

    DELETE 在Mysql4.0之后,mysql开始支持跨表delete. Mysql可以在一个sql语句中同时删除多表记录,也可以根据多个表之间的关系来删除某一个表中的记录. 假定我们有两张表:Pr ...

  6. JavaScript DOM编程艺术-学习笔记(总结一)

    1.1)dom-core方法:(不专属于js,支持dom的任何一种程序设计语言都可以使用它,它们的用途,也不仅限于处理网页,也可以用来处理任何一种标记语言编写处理的文档)  ①getElementBy ...

  7. sqlserver和Windows资源管理器争用内存

    sqlserver和Windows资源管理器在设置成相同的优先级的情况下(普通),Windows资源管理器优先于sqlserver对内存的征用.开始是

  8. jquery属性与样式

    1.attr()与prop() 每个元素都有一个或者多个特性,这些特性的用途就是给出相应元素或者其内容的附加信息.如:在img元素中,src就是元素的特性,用来标记图片的地址. 操作特性的DOM方法主 ...

  9. Valid Number--LeetCode

    class Solution { public: bool isNumber(string s) { if(s == " ") return false; ; ; while(s[ ...

  10. mpich2 下运行时出现“由于目标计算机积极拒绝,无法连接”的错误

    进行mpi并行编程时候,win8下使用mpich2时候,安装目录下找到wmpiexec.exe程序打开,填入编写好的.exe程序地址并制定执行的任务数目的想要运行时候,出现错误: unable to  ...