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 }
  • 相关阅读:
    冲刺计划第五天
    冲刺计划第四天
    冲刺计划第三天
    冲刺计划第二天
    冲刺计划第一天
    本周总结(9)
    统计文章中得单词百分比、以及字母百分比
    梦断代码阅读笔记03
    maven仓库、jar包兼容问题
    SpringMVC异常映射
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14429330.html
Copyright © 2011-2022 走看看