P1351 联合权值
每个节点,他所连接的各个节点之间的距离都是2,因为一共那个点,所以两层循环只相当于nlogn
把一个点所连接的所有点求和,(k-a[i])*a[i]表示这个点和剩余所有的点的乘积的和,把每个点都如此处理,再把所得结果相加,即每个点和他相邻为2 的点的乘积得和
这……2020年10月的我再来看看这篇博客已经不知道自己在写啥了,也不知道自己在讲啥,但是看阅读量还比较可观就不删了吧……
1 #include <cstdio>
2 #include <iostream>
3 #include <vector>
4 using namespace std;
5 const int maxn = 200100;
6 long long n,weight[maxn];
7 long long st[maxn],ed[maxn];
8 vector <long long> num[maxn];
9 long long start[maxn],end[maxn],pluss[maxn],tmp[maxn],tmp2[maxn];
10 int main()
11 {
12 scanf ("%d",&n);
13 for (int i = 1;i <= n-1;i++)
14 {
15 scanf ("%d%d",&start[i],&end[i]);
16 num[start[i]].push_back(end[i]);
17 num[end[i]].push_back(start[i]);
18 }
19 for (int i = 1;i <= n;i++)
20 {
21 scanf ("%d",&weight[i]);
22 }
23 for (int i = 0;i < n;i++)
24 {
25 for (int j = 0;j < num[i].size();j++)
26 {
27 tmp[i]=max(tmp[i],weight[num[i][j]]);
28 }
29 }
30 for (int i = 0;i < n;i++)
31 {
32 for (int j = 0;j < num[i].size();j++)
33 {
34 if (weight[num[i][j]]==tmp[i])
35 {
36 ed[i]=j;
37 break;
38 }
39 }
40 }
41 for (int i = 0;i < n;i++)
42 {
43 for (int j = 0;j < num[i].size();j++)
44 {
45 if (j!=ed[i])
46 tmp2[i]=max(tmp2[i],weight[num[i][j]]);
47 }
48 }
49 long long answer=0;
50 for (int i = 0;i < n;i++)
51 {
52 answer=max(tmp[i]*tmp2[i],answer);
53 }
54 cout<<answer<<" ";
55 long long ans=0;
56 for (int i = 1;i < n;i++)
57 {
58 for (int j = 0;j < num[i].size();j++)
59 {
60 pluss[i]+=(weight[num[i][j]])%10007;
61 }
62 }
63 for (int i = 1;i < n;i++)
64 {
65 for (int j = 0;j < num[i].size();j++)
66 {
67 ans+=(pluss[i]-weight[num[i][j]])*weight[num[i][j]]%10007;
68 }
69 }
70 cout<<ans%10007;
71 return 0;
72 }