【洛谷P1351】[NOIP2014]联合权值

联合权值

题目链接

首先,直接两重循环暴力枚举得了70分

然后发现第二重循环可以记忆化一下

记忆一下每个点的子节点的权值和、最大值、

次大值(为了处理该点的父节点权值恰好为最大值)

具体看代码

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define N 400010
 6 #define int long long
 7 int n,w[N],Head[N],tot;
 8 int Max,Sum,sum[N],max1[N],max2[N];
 9 inline int read(){
10     int x=0; char c=getchar();
11     while(c<'0'||c>'9') c=getchar();
12     while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
13     return x;
14 }
15 struct NODE{
16     int to,next;
17 } e[N<<1];
18 inline void add(int x,int y){
19     e[++tot].to=y;
20     e[tot].next=Head[x];
21     Head[x]=tot;
22 }
23 #undef int
24 int main()
25 #define int long long
26 {
27     n=read();
28     int x,y;
29     for(int i=1;i<n;i++){
30         x=read(); y=read();
31         add(x,y); add(y,x);
32     }
33     for(int i=1;i<=n;i++)
34      w[i]=read();
35     for(int i=1;i<=n;i++)
36      for(int j=Head[i];j;j=e[j].next){
37         int son=e[j].to;
38         if(!sum[son]&&!max1[son])
39             for(int k=Head[son];k;k=e[k].next){
40                 int gson=e[k].to;
41                 if(max2[son]<w[gson]){
42                     max2[son]=w[gson];
43                     if(max2[son]>max1[son])
44                      swap(max1[son],max2[son]);
45                 }
46                 sum[son]+=w[gson];
47             }
48         if(w[i]!=max1[son])
49             Max=max(Max,max1[son]*w[i]);
50         else Max=max(Max,max2[son]*w[i]);
51         Sum=(Sum+(sum[son]-w[i])*w[i])%10007;
52      }
53     printf("%lld %lld",Max,Sum);
54     return 0;
55 }

 

posted @ 2018-07-17 21:17  yjk  阅读(116)  评论(0编辑  收藏  举报