• 联合权值


    题目描述

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

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

    输入格式

    第一行包含 1 个整数 n。

    接下来 n1 行,每行包含 2 个用空格隔开的正整数 u,v,表示编号为 u 和编号为 v 的点之间有边相连。

    最后 1 行,包含 n 个正整数,每两个正整数之间用一个空格隔开,其中第 i 个整数表示图 G 上编号为 i 的点的权值为 W_i

    输出格式

    输出共 1 行,包含 2个整数,之间用一个空格隔开,依次为图 G 上联合权值的最大值和所有联合权值之和。由于所有联合权值之和可能很大,输出它时要对10007取余。

    输入输出样例

    输入 #1
    5  
    1 2  
    2 3
    3 4  
    4 5  
    1 5 2 3 10 
    输出 #1
    20 74


    分析:
    本题有个非常显然的结论:就是能产生联合权值的都是有一个中间点遍历得到的两个点,于是就算法十分显然,遍历每一个点然后寻找相邻结点就完事了。
    但是:众所周知,NOIP是毒瘤,所以没这么简单,如果只是暴力统计答案会超时。
    所以我们用一种奇妙的方法来统计就行了。(完工)
    不过话说这题算法是:暴力?(huaji)
    CODE:
     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 const int M=400005;
     8 const int mod=10007;
     9 int n;
    10 int tot,head[M],to[M],next[M];
    11 int w[M],maxn,ans;
    12 int get(){
    13     int res=0,f=1;
    14     char c=getchar();
    15     while (c>'9'||c<'0') {
    16         if (c=='-') f=-1;
    17         c=getchar();
    18     }
    19     while (c<='9'&&c>='0'){
    20         res=(res<<3)+(res<<1)+c-'0';
    21         c=getchar();
    22     }
    23     return res*f;
    24 }
    25 void add(int u,int v){
    26     next[++tot]=head[u];
    27     head[u]=tot;
    28     to[tot]=v;
    29     return ;
    30 }
    31 int sum,maxx,ansl;
    32 int main(){
    33     n=get();
    34     for (int i=1;i<n;i++){
    35         int u=get(),v=get();
    36         add(u,v);add(v,u);
    37     }
    38     for (int i=1;i<=n;i++) w[i]=get();
    39     for (int i=1;i<=n;i++){
    40         sum=w[to[head[i]]];
    41         maxx=w[to[head[i]]];
    42         ansl=0;
    43         //cout<<i<<endl;
    44         for (int j=next[head[i]];j;j=next[j]){
    45             maxn=max(maxn,maxx*w[to[j]]);
    46             maxx=max(maxx,w[to[j]]);
    47             ansl+=sum%mod*w[to[j]]%mod;
    48             sum+=w[to[j]]%mod;
    49             //cout<<maxx<<" "<<maxn<<" "<<ansl<<" "<<sum<<endl;
    50         }
    51         ans+=ansl*2;
    52         ans%=mod;
    53         //cout<<ans<<endl<<endl;
    54     }
    55     printf ("%d %d
    ",maxn,ans);
    56     return 0;
    57 }


  • 相关阅读:
    数据结构总结——线段树
    [bzoj2131]免费的馅饼 树状数组优化dp
    [机房练习赛7.26] YYR字符串
    博客已搬家
    AFO
    COGS-2551 新型武器
    UVALive-3716 DNA Regions
    UVALive-4850 Installations
    UVALive-3983 Robotruck
    UVA-10859 Placing Lampposts
  • 原文地址:https://www.cnblogs.com/kanchuang/p/11380226.html
Copyright © 2020-2023  润新知