首页 > 代码库 > [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();}
[noip2014day1-T2]联合权值
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。