zoukankan      html  css  js  c++  java
  • NOIP 提高组 2014 联合权值(图论???)

    传送门

    https://www.cnblogs.com/violet-acmer/p/9937201.html

    题解:

      相关变量解释:

    int n;
    int fa[maxn];//fa[i] : i的父亲节点
    int w[maxn];//w[i] : i的权值
    long long sum[maxn];//sum[i] : i节点的所有儿子节点的权值和
    int maxSon1[maxn];//maxSon1[i] : i节点的所有儿子中权值最大值(如果有超过两个儿子)
    int maxSon2[maxn];//maxSon2[i] : i节点的所有儿子中权值第二大值(如果有超过两个儿子)
    vector<int >G[maxn];//存边
    vector<int >son[maxn];//son[i] : 记录节点 i 的所有儿子节点

      步骤:

      (1):先Dfs(u,f)预处理出节点u的父亲节点fa[u],儿子节点son[u],儿子节点的权值和sum[u],以及儿子节点的权值最大的前两个权值maxSon1[u],maxSon2[u];

      (2):如果某节点 i 含有两个及以上儿子,则每两个儿子间也可构成长度为 2 的边长,求出节点 i 的儿子节点的联合权值,并判断是否可以更新联合权值的最大值;

      (3):求 i 节点与其父亲的父亲节点 j 构成的联合权值,并将其二倍(i 与 j 构成联合权值,同样 j 与 i 也可以构成联合权值,所以需要加入两个)与加入到联合权值之和

           中,并判断是否可以更新联合权值的最大值。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define pb(x) push_back(x)
     4 #define mem(a,b) memset(a,b,sizeof(a))
     5 const int maxn=200000+10;
     6 const int MOD=10007;
     7 
     8 int n;
     9 int fa[maxn];
    10 int w[maxn];
    11 long long sum[maxn];
    12 int maxSon1[maxn];
    13 int maxSon2[maxn];
    14 vector<int >G[maxn];
    15 vector<int >son[maxn];
    16 void addEdge(int u,int v)
    17 {
    18     G[u].pb(v);
    19     G[v].pb(u);
    20 }
    21 void Dfs(int u,int f)
    22 {
    23     fa[u]=f;
    24     for(int i=0;i < G[u].size();++i)
    25     {
    26         int to=G[u][i];
    27         if(to != f)
    28         {
    29             son[u].pb(to);
    30             sum[u] += w[to];
    31             if(w[to] > maxSon1[u])
    32             {
    33                 if(maxSon1[u] > maxSon2[u])
    34                     maxSon2[u]=maxSon1[u];
    35                 maxSon1[u]=w[to];
    36             }
    37             else if(w[to] > maxSon2[u])
    38                 maxSon2[u]=w[to];
    39             Dfs(to,u);
    40         }
    41     }
    42 }
    43 
    44 void Solve()
    45 {
    46     mem(sum,0);
    47     mem(maxSon1,0);
    48     mem(maxSon2,0);
    49     Dfs(1,-1);
    50     int maxRes=0;
    51     int res=0;
    52     for(int i=1;i <= n;++i)//步骤(2)
    53     {
    54         if(son[i].size() >= 2)
    55         {
    56             maxRes=max(maxRes,maxSon1[i]*maxSon2[i]);
    57             for(int j=0;j < son[i].size();++j)
    58                 res=res%MOD+((sum[i]-w[son[i][j]])%MOD)*(w[son[i][j]]%MOD);
    59         }
    60     }
    61     for(int i=2;i <= n;++i)//步骤(1)
    62     {
    63         if(fa[i] != 1)
    64         {
    65             maxRes=max(maxRes,w[fa[fa[i]]]*w[i]);
    66             res=res%MOD+2*w[fa[fa[i]]]*w[i];
    67         }
    68     }
    69     printf("%d %d
    ",maxRes,res%MOD);
    70 }
    71 int main()
    72 {
    73     scanf("%d",&n);
    74     for(int i=1;i < n;++i)
    75     {
    76         int u,v;
    77         scanf("%d%d",&u,&v);
    78         addEdge(u,v);
    79     }
    80     for(int i=1;i <= n;++i)
    81         scanf("%d",w+i);
    82     Solve();
    83 }
    View Code

      坑:  

        步骤(2)的情况刚开始忘了,然后,吃了一发wa.................

  • 相关阅读:
    <转>反调试技巧总结原理和实现
    反调试功能<IsDebuggerPresent>
    通过取得MAC地址判断是否在VM中
    任何值得拥有的东西
    我的程序里
    吸引力法则之谜——十一条被遗忘的定律
    要成功,请忘掉自尊
    我是个只顾着想,却不去做的人
    现在有12个金币,其中一个有质量问题(或重或轻),还有一个无砝码的天平,让你称三次怎么样找到那个有质量问题的金币?
    惆怅
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/9937458.html
Copyright © 2011-2022 走看看