zoukankan      html  css  js  c++  java
  • [noip2014day1-T2]联合权值

    无向连通图 G 有 n 个点,n-1 条边。点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi,每条边的长度均为 1。图上两点(u, v)的距离定义为 u 点到 v 点的最短距离。对于图 G 上的点对(u, v),若它们的距离为 2,则它们之间会产生Wu*Wv的联合权值。
    请问图 G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?

    题解:树形dp;

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<iomanip>
    #include<map>
    #include<set>
    #include<vector>
    #include<ctime>
    #include<cmath>
    #define LL long long 
    using namespace std;
    #define LL long long 
    #define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
    #define max(x,y) ((x)<(y)?(y):(x))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define FILE "1"
    const int maxn=202000,mod=10007;
    int read(){
        int x=0;bool flag=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flag=1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
        return flag?-x:x;
    }
    int n;
    
    struct node{
        int y,next;
    }e[maxn<<1];
    int linkk[maxn],len=0,w[maxn],maxx[maxn];
    int Max=0,Sum=0;
    void insert(int x,int y){
        e[++len].y=y;
        e[len].next=linkk[x];
        linkk[x]=len;
    }
    void init(){
        n=read();
        int x,y;
        up(i,2,n){
            x=read(),y=read();
            insert(x,y);insert(y,x);
        }
        up(i,1,n)w[i]=read();
    }
    int q[maxn],tail,head=0,fa[maxn],siz[maxn],ans[maxn],ru[maxn];
    void bfs(){
        head=tail=0;
        q[++tail]=1;int x;
        while(++head<=tail){
            x=q[head];
            for(int i=linkk[x];i;i=e[i].next){
                if(e[i].y==fa[x])continue;
                ru[x]++;
                fa[e[i].y]=x;
                q[++tail]=e[i].y;
            }
        }
        tail=0,head=0;
        up(i,1,n)if(!ru[i])q[++tail]=i;
        while(++head<=tail){
            x=q[head];
            ans[x]=(ans[x]+w[fa[x]]*siz[x])%mod;
            Sum+=ans[x];
            if(--ru[fa[x]]==0)q[++tail]=fa[x];
            ans[fa[x]]=(ans[fa[x]]+siz[fa[x]]*w[x])%mod;
            siz[fa[x]]=(siz[fa[x]]+w[x])%mod;
            Sum=(Sum+ans[x])%mod;
            if(w[x]*maxx[fa[x]]>Max)Max=w[x]*maxx[fa[x]];
            if(w[fa[x]]*maxx[x]>Max)Max=w[fa[x]]*maxx[x];
            if(w[x]>maxx[fa[x]])maxx[fa[x]]=w[x];
        }
        cout<<Max<<" "<<Sum<<endl;
    }
    int main(){
        freopen(FILE".in","r",stdin);
        freopen(FILE".out","w",stdout);
        init();
        bfs();
    }
    View Code
  • 相关阅读:
    docker
    SAML(Security assertion markUp language) 安全断言标记语言
    kafka消息系统
    OBS 对象存储技术学习
    AOP之AspectJ
    sql查漏补缺
    todolist
    springboot 注解整理
    前端之jQuery
    前端之BOM和DOM
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5948905.html
Copyright © 2011-2022 走看看