• cogs1804 联合权值 dp


    填坑……链接:http://cogs.pro/cogs/problem/problem.php?pid=1804

    题意:给出一棵树,定义两个距离为2的点权值乘积为这两个点产生的联合权值,求出整棵树最大联合权值及联合权值之和。

    实际上早就做过……现在重做旧题感觉还是很有必要……

    我们可以枚举每一个点作为可以产生联合权值的两点的中点,对于这个点来说,他周围的点权值之和就是

    sumlimits_{i=1}^N(sumlimits_{u,v in adj_i, u eq v} W_u imes W_v)

    然后对于每一个中点,他做出的贡献也就可以表示成

    S_i = sum_{j in adj_i} (W_j imes (sum_{k in adj_i} W_k) - W_j)

    然后大力化简可得

    S_i ={ (sum_{j in adj_i} W_j)} ^ 2 - sum_{j in adj_i} W_j^2

    这也就是我们需要的求和式子。

    至于最大的嘛……直接找到最大的和次大的相乘比较就可以了……

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int mod=10007,maxn=200005;
     7 struct node
     8 {
     9     int from,to,next;
    10 }edge[maxn<<1];
    11 int head[maxn],tot,n,weight[maxn];
    12 void addedge(int u,int v)
    13 {
    14     edge[++tot]=(node){u,v,head[u]};head[u]=tot;
    15 }
    16 int haha()
    17 {
    18     freopen("linkb.in","r",stdin);
    19     freopen("linkb.out","w",stdout);
    20     scanf("%d",&n);
    21     for(int i=1;i<n;i++)
    22     {
    23         int x,y;scanf("%d%d",&x,&y);
    24         addedge(x,y);addedge(y,x);
    25     }
    26     for(int i=1;i<=n;i++)scanf("%d",&weight[i]);
    27     int maxx=0;long long sum=0;
    28     for(int i=1;i<=n;i++)
    29     {
    30         int firmax=0,secmax=0;long long sigma=0,pow2sigma=0;
    31         for(int j=head[i];j;j=edge[j].next)
    32         {
    33             int v=edge[j].to;
    34             if(weight[v]>firmax)secmax=firmax,firmax=weight[v];
    35             else secmax=max(secmax,weight[v]);
    36             sigma=(sigma+weight[v]);pow2sigma=(pow2sigma+weight[v]*weight[v])%mod;
    37         }
    38         maxx=max(maxx,firmax*secmax);
    39         sum=(sum+sigma*sigma-pow2sigma)%mod;
    40     }
    41     printf("%d %lld",maxx,sum);
    42 }
    43 int sb=haha();
    44 int main(){;}
    cogs1804
  • 相关阅读:
    nok
    Applescript
    如何混编c++
    排序——希尔排序
    排序——插入排序(找坑)
    排序——选择排序
    排序——冒泡排序
    还债——Java中的Set, List, Map
    还债——Java中基本数据类型,String,数组之间转换(数组不能通过toString转换为String)
    还债——Java获取键盘输入的三种方法
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7357243.html
Copyright © 2020-2023  润新知