luoguP1351 联合权值

Posted tpgzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP1351 联合权值相关的知识,希望对你有一定的参考价值。

题目描述

无向连通图G 有n 个点,n - 1 条边。点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 。图上两点( u , v ) 的距离定义为u 点到v 点的最短距离。对于图G 上的点对( u, v) ,若它们的距离为2 ,则它们之间会产生Wu×Wv 的联合权值。

请问图G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?

思路:注意题目中这是一个无向连通图,且被n-1条边连着,这让我们想起什么呢,这就是一个树,而且退化成了一条链。所以我们只要枚举每个点,然后跟他连着的点的权值相乘就好了,最后还要乘以二,因为题目中要求我们求a—b&&b—a(就这么简单,懒得敲代码,上网找了一篇,放心,我会给你们注释的很明白的

 1 #include<cstdio>
 2 #include<cmath>
 3 using namespace std;
 4 struct Edge
 5 {
 6     int t,nexty;
 7 }edge[1000000];//链式前向星,不明白的没关系我可能已经发表了关于链式前向星的博客,请前去看看
 8 int head[300000]={0},cnt=0;//关于建图
 9 void add(int a,int b)
10 {
11     cnt++;
12     edge[cnt].t=b,edge[cnt].nexty=head[a];
13     head[a]=cnt;
14 }
15 long long w[300000]={0};//w数组代表点的值
16 int main()
17 {
18     int n;//n个点
19     scanf("%d",&n);//输入
20     int a,b;//a点,b点
21     for(int i=0;i<n-1;i++)
22     {
23         scanf("%d%d",&a,&b);//输入a,b俩点
24         add(a,b),add(b,a);//a,b俩点之间建边
25     }
26     for(int i=1;i<=n;i++)scanf("%lld",&w[i]);//输入点的值
27     long long sum=0,maxn=0;//sum记录着联合权值的总和,maxn记录最大值的联合权值
28     long long he,rmax;//he表示当前的和,rmax是指当前的最大值
29     int node;//后面领悟吧,不好说,可以换掉这个
30     for(int i=1;i<=n;i++)
31     {
32         node=head[i];//这关
33         he=(rmax=w[edge[node].t])%10007;//此时的he要等于他的一条边连这那个点的值
34         node=edge[node].nexty;//换另一条边
35         for(;node!=0;node=edge[node].nexty)//核心代码,后方高能
36         {
37             sum=(sum+he*w[edge[node].t])%10007;//总和要加上联合权值的和
38             maxn=max(maxn,rmax*w[edge[node].t]);//最大值要与此时的最大值进行比较
39             he=(he+w[edge[node].t])%10007;//和要加上第二条边所连点的值
40             rmax=max(rmax,w[edge[node].t]);//rmax进行更新
41         }
42     }
43     printf("%lld %lld",maxn,(sum*2)%10007);//输出
44     return 0;
45 }

 

以上是关于luoguP1351 联合权值的主要内容,如果未能解决你的问题,请参考以下文章

题解luogup1351 NOIp提高组2014 联合权值

Luogu P1351 联合权值 题解

P1351 联合权值

P1351 联合权值

P1351 联合权值

P1351 联合权值