• $Noip2014/Luogu1351$ 联合权值 树形


    $Luogu$

    $Description$

    给定一棵树,每两个距离为$2$的点之间可以产生"联合权值","联合权值"定义为这两个数的乘积.求最大的联合权值以及所有的联合权值之和.注意这两个数是有序的,翻译成人话就是求完和之后要$*2$.

    $Sol$

    想起了消防局的设立$ovo$.

    距离为$2$的点,它们不是兄弟就是祖孙,那直接$dfs$一遍更新答案就好了叭.

    兄弟之间更新答案这里有两个优化:

    1.贪心.把所有的兄弟加入数组$s$之后按照$w[i]$从大到小排序,一遍枚举$i>1$,

    用$w[s[i]]*w[s[1]]$更新最大值.

    2.乘法分配率.假设这里有三个兄弟的权值分别为$a,b,c$,那么联合权值之和就是

    $a*b+a*c+b*c=a*(b+c)+b*c$.说到这里小学生都会了$ovo$.

    $Code$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define il inline
    #define Rg register
    #define go(i,a,b) for(Rg int i=a;i<=b;++i)
    #define yes(i,a,b) for(Rg int i=a;i>=b;--i)
    #define e(i,u) for(Rg int i=b[u];i;i=a[i].nt)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define db double
    #define inf 2147483647
    using namespace std;
    il int read()
    {
        Rg int x=0,y=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*y;
    }
    const int N=200010,mod=10007;
    int n,ct,b[N],w[N],as1,as2;
    struct node{int v,nt;}a[N*2];
    il void add(int u,int v){a[++ct]=(node){v,b[u]};b[u]=ct;}
    il bool cmp(int x,int y){return w[x]>w[y];}
    il void dfs(int u,int f)
    {
        Rg int s[N],nm=0,dat;s[0]=0;
        e(i,u)
        {
            Rg int v=a[i].v;
            if(v==f)continue;
            dfs(v,u);
            s[++nm]=v;
            dat=w[v]*w[f];
            as1=max(as1,dat);as2=(as2+dat%mod)%mod;
        }
        sort(s+1,s+nm+1,cmp);
        go(i,2,nm)as1=max(as1,w[s[i]]*w[s[1]]);
        go(i,1,nm)s[i]=(s[i-1]+w[s[i]])%mod;
        go(i,2,nm)as2=(as2+(s[i]-s[i-1])*s[i-1])%mod;
    }
    int main()
    {
        n=read();
        go(i,1,n-1){Rg int u=read(),v=read();add(u,v);add(v,u);}
        go(i,1,n)w[i]=read();
        dfs(1,0);
        printf("%d %d
    ",as1,as2*2%mod);
        return 0;
    }
    View Code

     

  • 相关阅读:
    String.prototype.getParm
    IOS—通过ChildViewController实现view的切换
    objective-c IBOutletCollection介绍
    iOS方法类:CGAffineTransform的使用大概
    cocoaPods下载使用记录
    objective-c 中的关联介绍
    操作系统--文件管理
    操作系统--设备管理
    操作系统--存储管理的任务
    操作系统--并发进程死锁
  • 原文地址:https://www.cnblogs.com/forward777/p/11411429.html
Copyright © 2020-2023  润新知