Luo Gu P1351 (enumeration)

### Los Valley P1351 topic Link ###

 

Subject to the effect:

You n nodes, n-1 sides of the article without the Unicom FIG. If the definition of (u, v) represents the shortest distance from the point u and v, if (u, v) is 2, the right of the plot points of the two points (i.e., W is * W is v ) known as the Joint weight, and the sum of the maximum combined weights of the combined weights of perfection in FIG.

 

analysis:

1, since n-1 edges and undirected connected graph, FIG easily determine the root of the tree is free of.

2, then we can traverse the full picture of all the nodes, then the son of the relative distance of these nodes are the nodes 2.

3, if the two nodes A son of ab, they contribute to the answer, then there can not be a second node also has two nodes as the son of ab. So this enumeration is not repeated.

4, logically speaking, we need to traverse all the sons of this node node, followed by summation answer. But can be found through the analysis:  if ab two sons, then the contribution == 2 * ab (A + b) 2 - (A 2 + b 2 ); likewise if three sons abc, the contribution to the 2 * ab 2 * 2 + AC + BC == * (A + B + C) 2  - (A 2 + B 2 + C 2 ).  You can turn statistics and the square and then finally you can handle it.

 5, for determining the maximum: son node A node maximum product of the two right point, that is, A is the maximum value of the combined weight parent node. So long as the father takes the largest node of the maximum combined weight can be.

 

code show as below: 

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define maxn 200008
typedef long long ll;
const ll mod = 10007;
int n,cnt;
int head[maxn],in[maxn];
ll a[maxn];
struct Edge{
    int to;
    int next;
}edge[maxn<<1];
inline void add(int u,int v){
    edge[++cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt;
    return;
}
int main(){
    scanf("%d",&n);
    int A,B;
    for (int i=1; i <= n-1; i++) {
        scanf("%d%d",&A,&B);
        add(A,B),add(B,A);
        in[A]++,in[B]++;
    }
    for (int i=1; i <= n; i++)  scanf("%lld",&a[i]);
    ll ans=0,res=0;
    for (int i=1; i <= n; i++) {
        if(in[i]<=1) continue;
        ll s1=0,s2=0;
        ll MMax=0,mmax=0;
        for(int j=head[i];j;j=edge[j].next){
            int v=edge[j].to;
            s1=(s1+a[v])%mod,s2=(s2+a[v]*a[v]%mod)%mod;
            if(a[v]>=MMax){mmax=MMax;MMax=a[v];}
            else if(a[v]>mmax) mmax=a[v];
        }
        ll k = ((s1*s1)%mod-s2+mod)%mod;
        ans=(ans+k)%mod;
        res=max(res,MMax*mmax);
    }
    printf("%lld %lld\n",res,ans);
}

 

Guess you like

Origin www.cnblogs.com/Absofuckinglutely/p/11595088.html