zoukankan      html  css  js  c++  java
  • NOIP之旅:NOIP2014篇

    A. 联合权值

    标签:思维题,图论

    该题浑身上下都是坑  果然还是我太弱了。

    首先看题看的一脸懵逼,然后根据数据(n个点 n-1条边)我们知道其实这就是棵树嘛qwq

    任务目标:求出最大联合权值,求所有联合权值之和。

    主流题解有两条路:思维+技巧,树形DP

    思维+技巧:首先构建基本模型。以一个点为中心,与其直接相邻的点互相为可联合的点,因为显然它们与该点距离为1,根据树的性质它们彼此之间的路径必定经过该点,即相互距离为2。 那么枚举每个点的每条边进行结算。对于任务目标2,我们可以看样例得出某些.... ...目标为a*b+b*c+......b*a+c*b. 经过简单的思考,继续套用上文模型,定义s[o]为指定点邻点的权值之和,定义ABCDEFG等一干字母为邻点,那么对于该点答案为 val[A]*(s[o]-val[A]) + ...

    顺便吐槽某些题解:这是乘法分配律,不是什么加法结合律

     1 #include<cstdio>
     2 #include<iostream>
     3 #define maxn 500000
     4 using namespace std;
     5 
     6 struct edge{
     7     long long from,v;
     8 }e[maxn];
     9 
    10 long long tot,first[maxn];
    11 void insert(long long u,long long v){
    12     tot++;
    13     e[tot].from = first[u];
    14     e[tot].v = v;
    15     first[u] = tot;
    16 }
    17 
    18 long long n,u,v,s[maxn],val[maxn],cnt1,cnt2,maxx[maxn],sum,ans;
    19 int main(){
    20     scanf("%lld",&n);
    21     for(long long i = 1;i < n;i++){
    22         scanf("%lld%lld",&u,&v);
    23         insert(u,v);
    24         insert(v,u);
    25     }
    26     
    27     for(long long i = 1;i <= n;i++){
    28         scanf("%lld",&val[i]);
    29     }
    30     
    31     for(long long i = 1;i <= n;i++){
    32         cnt1 = cnt2 = 0;
    33         for(long long j = first[i];j;j = e[j].from){
    34             v = e[j].v;
    35             s[i] += val[v];
    36 //            printf("$ %d",val[v]);
    37             if(val[v] >= cnt1){
    38                 cnt2 = cnt1,cnt1 = val[v];
    39 //                printf("##%d %d",cnt1,cnt2);
    40             }else if(val[v] > cnt2) cnt2 = val[v];
    41         }
    42 //        cout << endl;
    43         maxx[i] = cnt1*cnt2;
    44     }
    45     
    46     for(long long i = 1;i <= n;i++){
    47         ans = max(maxx[i],ans);
    48         for(long long j = first[i];j;j = e[j].from){
    49             sum = (sum+(s[i]-val[e[j].v])*val[e[j].v]); sum %= 10007;
    50         }
    51         
    52     }
    53     
    54     printf("%lld %lld
    ",ans,sum);
    55     
    56 //    for(int i = 1;i <= n;i++) printf("%d ",maxx[i]);
    57     
    58     return 0;
    59 }
    易证Leo_CT相当菜= =
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    archlinux .bash_history
    Ubuntu环境下挂载新硬盘
    软碟通 UltraISO U启替代品 Win32DiskImager 无设备 无盘符 无u盘 无优盘 解决方案 之diskpart
    delphi Integer overflow
    MSBuild Tools offline
    delphi synedit免费的拼写检查器dll
    git 自定义命令行
    lua编译
    gcc ar
    Windows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7376553.html
Copyright © 2011-2022 走看看