NOIP2014联合权值
无向连通图G有n个点,n-1条边。点从1到n依次编号,编号为i的点的权值为Wi ,每条边的长度均为1。图上两点(u, v)的距离定义为u点到v点的最短距离。对于图G上的点对(u, v),若它们的距离为2,则它们之间会产生Wu×Wv的联合权值。
请问图G上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?
题目链接:codevs http://www.cnblogs.com/smileandyxu/p/5348411.html
图论问题,70分暴力都很好打吧,只要枚举所有点dfs找到他的距离为二的点,维护一个tot和一个max就可以了,细节自己想想,代码
等下会贴出来,正解是乘法的结合律,这个题目可以转换一下,对于每个点对,可以看成由一点中间点中转而成,就是每个点对中必定有
且只隔一个点吧,因为图是棵树,只要枚举每个入度为1的点作为中转点,然后将其儿子与其他所有儿子相乘就可以了,但这是n平方的啊!会超时。
所以我们用乘法原理,统计所有儿子权值和,然后用权值和剪去自己的权值的值再乘自己的权值,这样就是O(n)完成了。
另外,推荐我的博客:http://www.cnblogs.com/renjianshige/
暴力代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<cstring>
const int MAXN=;
using namespace std;
struct edge{
int first;
int next;
int to;
int quan;
}a[*MAXN];
bool b[MAXN];
struct node{
int now;
int fa;
node(){}
node(int _now,int _fa):now(_now),fa(_fa){}
};
int dian[MAXN];
int in[MAXN];
int n,num=;
void addedge(int from,int to){
a[++num].to=to;
a[num].quan=;
a[num].next=a[from].first;
a[from].first=num;
}
long long tott=,big=;
void dfs(int now,int fa,int time){
for(int i=a[now].first;i;i=a[i].next){
int to=a[i].to;
if(to==fa) continue;
if(time==){
if(b[to]) continue;
long long dianquan=dian[fa]*dian[to];
big=max(big,dianquan);
tott=(tott+dianquan)%;
continue;
}
dfs(to,now,time+);
}
}
int main(){
memset(dian,,sizeof(dian));
memset(b,,sizeof(b));
scanf("%d",&n);
for(int i=;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
for(int i=;i<=n;i++){
scanf("%d",&dian[i]);
}
for(int i=;i<=n;i++){
dfs(i,,);
b[i]=;
}
printf("%lld %lld\n",big,(tott*)%);
return ;
}
AC代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<cstring>
const int MAXN=;
using namespace std;
struct edge{
int first;
int next;
int to;
int quan;
}a[*MAXN];
bool b[MAXN];
int dian[MAXN];
int in[MAXN];
int n,num=;
void addedge(int from,int to){
a[++num].to=to;
a[num].quan=;
a[num].next=a[from].first;
a[from].first=num;
}
long long tott=,big=;
void dfs(int now){
long long tot=,big1=,big2=;
for(int i=a[now].first;i;i=a[i].next){
int to=a[i].to;
tot=(tot+dian[to])%;
if(dian[to]>big1)
{
big1=dian[to];
continue;
}
if(dian[to]<=big1&&dian[to]>big2) big2=dian[to];
}
for(int i=a[now].first;i;i=a[i].next){
tott+=dian[a[i].to]*(tot-dian[a[i].to])%;
if(tott<) tott+=;
tott=tott%;
}
if(big<big1*big2) big=big1*big2;
}
int main(){
memset(dian,,sizeof(dian));
memset(b,,sizeof(b));
scanf("%d",&n);
for(int i=;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
in[x]++;
in[y]++;
}
for(int i=;i<=n;i++){
scanf("%d",&dian[i]);
}
for(int i=;i<=n;i++){
if(in[i]==) continue;
dfs(i);
}
printf("%lld %lld\n",big,tott%);
return ;
}
NOIP2014联合权值的更多相关文章
- [Luogu 1351] NOIP2014 联合权值
[Luogu 1351] NOIP2014 联合权值 存图,对于每一个点 \(u\),遍历它的所有邻接点.以 \(u\) 为中转点的点对中,\((x,y)\) 的联合权值 \(w_x \cdot w_ ...
- NOIP2014 联合权值
2.联合权值 (link.cpp/c/pas) [问题描述] 无向连通图G有n个点,n-1条边.点从1到n依次编号,编号为i的点的权值为Wi ,每条边的长度均为1.图上两点(u, v)的距离定义为u ...
- 【洛谷P1351】[NOIP2014]联合权值
联合权值 题目链接 首先,直接两重循环暴力枚举得了70分 然后发现第二重循环可以记忆化一下 记忆一下每个点的子节点的权值和.最大值. 次大值(为了处理该点的父节点权值恰好为最大值) 具体看代码 #in ...
- [NOIP2014]联合权值 题解
题目大意: 有一棵树,求距离为2的点权的乘积的和以及最大值. 思路: 枚举每一个点,则与其相邻的点互为距离为2的点.该部分的最大值为点权最大的两个点的积,和为点的权值和的平方减去每个点的平方,这样每条 ...
- luogu1351 [NOIp2014]联合权值 (dfs)
有两种情况:一个点到它的父亲的父亲(要算两次).一个点的子节点之间互相到达 #include<bits/stdc++.h> #define pa pair<int,int> # ...
- NOIP 2004 联合权值
洛谷 P1351 联合权值 洛谷传送门 JDOJ 2886: [NOIP2014]联合权值 D1 T2 JDOJ传送门 Description 无向连通图 G有 n个点,n-1条边.点从 1到 n依次 ...
- [NOIP2014] 提高组 洛谷P1351 联合权值
题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...
- Noip2014 提高组 T2 联合权值 连通图+技巧
联合权值 描述 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 WiWi, 每条边的长度均为 1.图上两点(u, v)的距离定义为 u 点到 v 点的 ...
- NOIP2014提高组第二题联合权值
还是先看题吧: 试题描述 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi ,每条边的长度均为 1.图上两点(u, v)的距离定义为 u 点到 ...
随机推荐
- 1、pytest中文文档--安装和入门
目录 安装和入门 安装pytest 创建你的第一个测试用例 执行多个测试用例 检查代码是否触发一个指定的异常 在一个类中组织多个测试用例 申请一个唯一的临时目录用于功能测试 安装和入门 Python版 ...
- 基于soot的java方法名生成报告
0.生成XML格式文件 笔者使用soot将java文件解析生成xml格式文档,具体操作流程不再赘述.本文讨论执行结果的用途.笔者第一次采用的java文件如下:文件名为test.java 用soot解析 ...
- ERROR IN RESOURCESTART
TOMCAT启动时出现这个问题,试遍了网上所有的方法就是不管用,卸载tomcat重新安装即可
- [1]尝试用Unity3d制作一个王者荣耀(持续更新)->AssetBundle管理器
如果已经看过本章节:目录传送门:这是目录鸭~ 1.AssetBundleManager: 首先我们创建一个文件夹,叫AssetBundleManager,再创建Csharp(即C#)脚本,名为Asse ...
- vmware vsphere client 创建虚拟机
浏览器访问https://192.168.120.29 用户名:administrator@zhcs.com 密码: Deyi123456! 说明:此案例为创建linux的Centos7的操作系统的 ...
- apache ignite系列(六): 服务网格
简介 服务网格本质上还是远程方法调用(RPC),而在ignite中注册的服务本质体现还是以cache的形式存在,集群中的节点可以相互调用部署在其它节点上的服务,而且ignite集群会负责部署服务的 ...
- Hive函数大全-完整版
现在虽然有很多SQL ON Hadoop的解决方案,像Spark SQL.Impala.Presto等等,但就目前来看,在基于Hadoop的大数据分析平台.数据仓库中,Hive仍然是不可替代的角色.尽 ...
- 浅谈ViewPager与TabLayout的简单用法
今天介绍一下ViewPager与TabLayout的简单用法 1.准备 在一切开始之前,你懂得,先导库,老方法,在build.gradle直接添加下面这一句 implementation ...
- 表达式树练习实践:C#值类型、引用类型、泛型、集合、调用函数
目录 表达式树练习实践:C#值类型.引用类型.泛型.集合.调用函数 一,定义变量 二,访问变量/类型的属性字段和方法 1. 访问属性 2. 调用函数 三,实例化引用类型 四,实例化泛型类型于调用 五, ...
- Recovery启动流程--recovery.cpp分析
这篇文章主要通过分析高通recovery目录下的recovery.cpp源码,对recovery启动流程有一个宏观的了解. 当开机以后,在lk阶段,如果是recovery,会设置boot_into_r ...