noip2014联合权值
来源:互联网 发布:扭矩补偿算法 编辑:程序博客网 时间:2024/05/21 09:55
这道题其实重点在于抓住一个细节,每条边的长度均为1,若它们的距离为2。
这代表着啥?
就是说,两两结点的联合权值,必定经过另外一个结点。所以说,枚举的时候,只需要枚举每一个结点以及与这个节点相邻的点。然后把这些结点两两配对相乘相加,就Ok了。可是,这样还是抄了。。。。怎么再优化?
我们再次分析一下。对于最大值,明显只需要贪心。在每个结点中选择最大的两个即可。这个不需要考虑。那么,总和值是否可以优化呢?假设一个结点o,与其相连结点的权值为a1,a2,a3,a4……ai,那么,答案sum=(a1*a2+a1*a3+……a1*ai)+(a2*a1+a2*a3+……a2*ai)+……+(ai*a1+ai*a2+……ai*ai-1)这个时候,再进行乘法结合律,我们发现,其实就是这些结点中,该结点的权值乘上所有结点权值减去他自己的权值。比较绕口,写成表达式就是aj*(sum[o]-aj)其中sum[o]表示的是与o相连的所有结点的权值之和。这样,预处理一下就Ok啦。算法的时间复杂度应该是O(kn),k应该是一个远远小于n的数吧
贴代码:
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#define mod 10007
using namespace std;
vector<int>a[200001];
int w[200001];
int sum[200001];
int main()
{
intn;
cin>>n;
for(inti=1;i<=n-1;i++)
{
intx,y;
scanf("%d%d",&x,&y);
a[x].push_back(y);
a[y].push_back(x);
}
for(inti=1;i<=n;i++) cin>>w[i];
for(inti=1;i<=n;i++)
{
for(intj=0;j<a[i].size();j++)
{
sum[i]+=w[a[i][j]];
sum[i]%=mod;
}
}
intans=0,maxn=0;
for(inti=1;i<=n;i++)
if(a[i].size()!=1)
{
intmax1=w[a[i][0]];
intmax2=w[a[i][1]];
ans+=max1*(sum[i]-max1)+max2*(sum[i]-max2);
ans%=mod;
for(intj=2;j<a[i].size();j++)
{
intkk=w[a[i][j]];
inttt=kk;
if(tt>max1){swap(tt,max1);swap(tt,max2);}
elseif(tt>max2) {swap(tt,max2);}
ans+=kk*(sum[i]-kk);
ans%=mod;
}
maxn=max(maxn,max1*max2);
}
printf("%d%d\n",maxn,ans);
return0;
}
- NOIP2014 联合权值
- NOIP2014联合权值
- NOIP2014联合权值
- 【noip2014】联合权值
- NOIP2014 联合权值
- 【NOIP2014】 联合权值
- noip2014联合权值
- NOIP2014 联合权值
- 【NOIP2014】联合权值
- 【NOIP2014 联合权值】
- [NOIP2014]联合权值
- NOIP2014联合权值
- [noip2014]联合权值
- 【NOIP2014提高】联合权值
- 【乱搞】noip2014联合权值
- 【NOIP2014】联合权值 乱搞
- 【NOIP2014】Day1T2 联合权值
- 联合权值 noip2014 dfs
- 玩JoinQuant的开始
- 【LeetCode】 Maximum Depth of Binary Tree 二叉树的最大深度
- php操作office文档
- ssh2远程连接linux服务器
- Jmeter性能测试
- noip2014联合权值
- 【Java基础】:线程的生命周期
- Java中线程通信的方法
- JAVA多线程打印ABC
- Nginx搭建
- 23种设计模式全解析
- JDBCUtil工具类回顾
- 分布式事务解决方案(三)
- PHP高级特性(Senior features of php)之异常处理