zoukankan      html  css  js  c++  java
  • 洛谷 P1351 [NOIP2014 提高组] 联合权值(dp)

    传送门


    解题思路

    先遍历一遍树,求出size[u](节点u的所有相邻节点的点权和),和图中联合权值的最大值。

    如何求最大值?

    求出每个点相连的点的第一大和第二大点权,相乘后与ans取max。

    再求和:

    再遍历一遍树,对于每个点u,答案加上w[u]*(size[v]-w[u])。

    AC代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<iomanip>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=200005;
     8 const int mod=10007;
     9 int n,p[maxn],cnt,w[maxn],fa[maxn];
    10 long long ans,size[maxn];
    11 struct node{
    12     int v,next;
    13 }e[maxn*2];
    14 void insert(int u,int v){
    15     cnt++;
    16     e[cnt].v=v;
    17     e[cnt].next=p[u];
    18     p[u]=cnt;
    19 }
    20 void dfs(int u,int f){
    21     long long max1=0,max2=0;
    22     fa[u]=f;
    23     for(int i=p[u];i!=-1;i=e[i].next){
    24         if(e[i].v!=f){
    25             dfs(e[i].v,u);
    26         }
    27         size[u]+=w[e[i].v];
    28         if(w[e[i].v]>max2) max2=w[e[i].v];
    29         if(max2>max1) swap(max2,max1);
    30     }
    31     ans=max(ans,max1*max2); 
    32 }
    33 void dfs2(int u){
    34     for(int i=p[u];i!=-1;i=e[i].next){
    35         if(e[i].v!=fa[u]) dfs2(e[i].v);
    36         ans+=w[u]*(size[e[i].v]-w[u]);
    37     }
    38 }
    39 int main(){
    40     memset(p,-1,sizeof(p));
    41     cin>>n;
    42     for(int i=1;i<n;i++){
    43         int u,v;
    44         scanf("%d%d",&u,&v);
    45         insert(u,v);
    46         insert(v,u);
    47     }
    48     for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    49     dfs(1,-1);
    50     cout<<ans<<" ";
    51     ans=0;
    52     dfs2(1);
    53     cout<<ans%mod;
    54     return 0;
    55 }
  • 相关阅读:
    无刷电机控制基本原理
    SPI 串行Flash闪存W25Q128FV 的使用(STM32F407)_软件篇
    CAN总线简介
    RS-232串口特性
    PLSQL 安装教程
    JS 常用正则表达式备忘录
    JS数组去重
    Js中Map对象的使用
    JS操作字符串
    前端小技巧
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14429330.html
Copyright © 2011-2022 走看看