首页 > 代码库 > [noip2014day1-T2]联合权值

[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

 

[noip2014day1-T2]联合权值