您的位置:首页 > 其它

【NOIP2014】联合权值

2016-11-08 07:27 459 查看
【codevs 3728】

3728 联合权值

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 黄金 Gold

题目描述



输入描述



输出描述



输入描述



输出描述



样例说明



数据范围及提示



首先这是棵树

然后我们来想,在一棵树上距离为2的情况:

第一种,两个点是爷爷与孙子的关系

第二种,两个点父亲相同,是兄弟关系

注意是点的权值

那么我们建树出来还是好做的

注意是有序点对

所以每对点的权值计算两次

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 200005;
const int P = 10007;
long long n,f,t,fa[MAXN];
long long tree[MAXN][2],w[MAXN];
long long sum[MAXN],ans = 0,maxn = 0;

int main()
{
memset(tree,0,sizeof(tree));
memset(sum,0,sizeof(sum));
memset(w,0,sizeof(w));
memset(fa,0,sizeof(fa));
scanf("%lld",&n);
for(int i = 1; i < n; i ++)
{
scanf("%lld %lld",&f,&t);
if(fa[t])   fa[f] = t;
else  fa[t] = f;
}
for(int i = 1; i <= n; i ++)    scanf("%lld",&w[i]);
for(int i = 1; i <= n; i ++)
{
long long fas = fa[fa[i]];
long long re = w[i] * w[fas];
maxn = max(maxn,re);
ans += re * 2;ans %= P;
sum[fa[i]] += w[i];
if(w[i] > tree[fa[i]][0])
{
tree[fa[i]][1] = tree[fa[i]][0];
tree[fa[i]][0] = w[i];
}
else if(w[i] > tree[fa[i]][1])
tree[fa[i]][1] = w[i];
}
for(int i = 1; i <= n; i ++)
{
ans += (sum[fa[i]] - w[i]) * w[i];
ans %= P;
long long re = tree[fa[i]][0] * tree[fa[i]][1];
maxn = max(maxn,re);
}
ans %= P;
printf("%lld %lld\n",maxn,ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: