【NOIP2014】 联合权值
2016-07-29 21:30
281 查看
无向连通图 G 有 n 个点,n-1 条边。点从 1 到 n 依次编号,编号为 i 的点的权值为
每条边的长度均为 1。图上两点(u, v)的距离定义为 u 点到 v 点的最短距离。对于图 G 上的点对(u, v),若它们的距离为 2,则它们之间会产生
请问图 G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?
第一行包含 1 个整数 n。
接下来 n-1 行,每行包含 2 个用空格隔开的正整数 u、v,表示编号为 u 和编号为 v 的点 之间有边相连。
最后 1 行,包含 n 个正整数,每两个正整数之间用一个空格隔开,其中第 i 个整数表示 图 G 上编号为 i 的点的权值为
输出共 1 行,包含 2 个整数,之间用一个空格隔开,依次为图 G 上联合权值的最大值 和所有联合权值之和。由于所有联合权值之和可能很大,输出它时要对10007取余。
对于 30%的数据,1 < n ≤ 100;
对于 60%的数据,1 < n ≤ 2000;
对于 100%的数据,1 < n ≤ 200,000,0 <
10,000
思路:乱搞
先想到暴力,然而暴力不好写那,于是想到每个点的出边与其距离为1,所以每个点的距离为1的结果是一定的,也就是说可以像DP一样利用起来,虽然是乘法,但是伟大的乘法分配驴就出现了!
然后统计最大值,一样的道理,不过由于对于一个定点,它去访问另外一个点的时候,预处理的最大值可能是它自己,所以最大值和次大值都需要存储,如果与最大值相等,那么就取次大值没跑了,否则就最大值。
我取模的姿势很挫,所以中途结果可能胡爆炸int,用了longlong,这在赛场上就是红果果的30分啊!!!
总的复杂度:统计权值和与极值,需要约n,然后计算更新需要n
所以最后应该是2n的算法
用了邻接表,这样明显快,用了读入优化,不过在vijos上ha
给你讲个笑话,有人在vijos上,把其他注释掉,只用cin读入不处理,然后最后三个点tle了
代码请食用~
WiWi,
每条边的长度均为 1。图上两点(u, v)的距离定义为 u 点到 v 点的最短距离。对于图 G 上的点对(u, v),若它们的距离为 2,则它们之间会产生
WuWu×
WvWv的联合权值。
请问图 G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?
输入格式
第一行包含 1 个整数 n。接下来 n-1 行,每行包含 2 个用空格隔开的正整数 u、v,表示编号为 u 和编号为 v 的点 之间有边相连。
最后 1 行,包含 n 个正整数,每两个正整数之间用一个空格隔开,其中第 i 个整数表示 图 G 上编号为 i 的点的权值为
WiWi。
输出格式
输出共 1 行,包含 2 个整数,之间用一个空格隔开,依次为图 G 上联合权值的最大值 和所有联合权值之和。由于所有联合权值之和可能很大,输出它时要对10007取余。对于 30%的数据,1 < n ≤ 100;
对于 60%的数据,1 < n ≤ 2000;
对于 100%的数据,1 < n ≤ 200,000,0 <
WiWi≤
10,000
思路:乱搞
先想到暴力,然而暴力不好写那,于是想到每个点的出边与其距离为1,所以每个点的距离为1的结果是一定的,也就是说可以像DP一样利用起来,虽然是乘法,但是伟大的乘法分配驴就出现了!
然后统计最大值,一样的道理,不过由于对于一个定点,它去访问另外一个点的时候,预处理的最大值可能是它自己,所以最大值和次大值都需要存储,如果与最大值相等,那么就取次大值没跑了,否则就最大值。
我取模的姿势很挫,所以中途结果可能胡爆炸int,用了longlong,这在赛场上就是红果果的30分啊!!!
总的复杂度:统计权值和与极值,需要约n,然后计算更新需要n
所以最后应该是2n的算法
用了邻接表,这样明显快,用了读入优化,不过在vijos上ha
给你讲个笑话,有人在vijos上,把其他注释掉,只用cin读入不处理,然后最后三个点tle了
代码请食用~
#include<iostream> #include<cstdio> #include<cstring> #include<limits.h> #include<algorithm> #include<vector> #include<queue> typedef long long ll; using namespace std; const int maxn=200005; const ll Mod=10007; ll an; ll h[maxn]; vector<int> g[maxn]; ll mx[3][maxn]; ll sm[maxn]; void git(ll &iii) { iii=0; int f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){iii=iii*10+ch-'0';ch=getchar();} if(f==-1) iii=-iii; } ll k, t2,n; ll t1; ll ans; int main() { git(n); for(int i=1;i<n;i++) { git(t1);git(t2); g[t1].push_back(t2); g[t2].push_back(t1); } for(int i=1;i<=n;i++) git(h[i]); for(int i=1;i<=n;i++) { if(g[i].empty()) continue; int lm=g[i].size(); int f1=0,f2=0; ll res=0; for(int j=0;j<lm;j++) { res+=h[g[i][j]]; if(h[g[i][j]]>f1) { f2=f1; f1=h[g[i][j]]; } else if(h[g[i][j]]==f1) { f2=h[g[i][j]]; } else if(h[g[i][j]]>f2) { f2=h[g[i][j]]; } } mx[0][i]=f1; mx[1][i]=f2; sm[i]=res; } for(int i=1;i<=n;i++) { if(g[i].empty()) continue; int lm=g[i].size(); for(int j=0;j<lm;j++) { int nw=g[i][j]; ans+=h[i]*(sm[nw]-h[i]); ans%=Mod; if(mx[0][nw]==h[i]) { an=max(an,mx[1][nw]*h[i]); } else an=max(an,mx[0][nw]*h[i]); } } cout<<an<<" "<<ans<<endl; }
相关文章推荐
- whichis,where,whatis等命令
- NKOI 1945 餐巾计划
- python3 fibonacci的高效解法
- 蓝色柠檬汽水的做法
- 第6课:spark机器学习第6课:spark机器学习算法介绍
- android studio 如何修改包名
- Codeforces Round #177 (Div. 1) C. Polo the Penguin and XOR operation(贪心)
- POJ 2923 DP
- 人见人爱A^B
- POJ 2923 DP
- nlogn的LIS(最长上升子序列)算法讲解
- Mutex互斥量线程同步的例子
- 跟我学Redis(1)—为什么学习Redis
- hdoj2095find your present (2)
- [HAOI2006]聪明的猴子
- cmd导入导出数据库
- 线段树基本知识
- String StringBuilder StringBuffer
- NOIP2016
- NYOJ1058部分和问题