【NOIP2014 联合权值】
2016-11-08 20:12
375 查看
#include <cstdio> #include <climits> const int MAXN = 200000 + 5; int MOD = 10007; struct Node; struct Edge; struct Node { int w; Edge *lastE; }N[MAXN]; struct Edge { Node *from, *to; Edge *next; Edge (Node *from, Node *to) : from(from), to(to), next(from->lastE) {} }; void AddEdge(int u, int v) { N[u].lastE = new Edge(&N[u], &N[v]); N[v].lastE = new Edge(&N[v], &N[u]); } int n; long long ans; int main() { scanf("%d", &n); for (int i = 0; i < n - 1; i++) { int u, v; scanf("%d %d", &u, &v); AddEdge(u, v); } for (int i = 1; i <= n; i++) scanf("%d", &N[i].w); int MAX = INT_MIN; for (int i = 1; i <= n; i++) { long long m = 0; //定义在函数内的变量要记得赋初值 int MAXm = 0, MINm = 0; for (Edge *e = N[i].lastE; e; e = e->next) { if (e->to->w >= MAXm){ MINm = MAXm; MAXm = e->to->w; } else if (e->to->w >= MINm) MINm = e->to->w; //这点没想到,这个点有可能是虽然不是最大的,但是是次大的 m += e->to->w; //这里m有可能爆int,所以要用long long } for (Edge *e = N[i].lastE; e; e = e->next) { (ans += ((m - e->to->w) * e->to->w) % MOD) %= MOD; } if (MAXm * MINm > MAX) { MAX = MAXm * MINm; } } printf("%d %lld\n", MAX, ans); return 0; }
代码是Sulfur6_L8972帮忙debug过的。
方法是Rachel教的。
就是一个点,以它为中心,周围所有点的联合权值之和为每一个互相相乘。例如有四个点A、B、C、D,和就为 A*B+A*C+A*D+B*A+B*C+B*D+C*A+C*B+C*D+D*A+D*B+D*C
= A(B+C+D)+B(A+C+D)+C(A+B+D)+D(A+C+D)
=A(m-A)+B(m-B)+C(m-C)+D(m-D).
但是教了方法我也懂了之后还是没能调出来,就是我的细节的锅了。不过感觉最近做了些题,积累了一些常见的错误及调试方法,也算有些收获。
主要的bug都在程序里注释出来了,另外还要注意主函数里的变量在哪里需要被重新定义,它的范围到哪里。
Sulfur6_L8972说也可以把
m += e->to->w;改成
m = (m + e->to->w) % MOD;但是模出来有可能是负的,需要在最后在加上啥啥啥再模一遍。
相关文章推荐
- 【NOIP2014提高组】联合权值——从60到100
- LuoguP1351[NOIP2014] 联合权值 解题报告【树形DP】
- Noip 2014 提高组 联合权值
- 【noip2014】联合权值
- 洛谷P1351 联合权值(NOIp2014)
- NOIP2014 联合权值
- NOIP 2014 D1T2 -联合权值
- NOIP2014联合权值
- NOIP 2014 T2 联合权值 DFS
- 【学术篇】luogu1351[NOIP2014 提高组]联合权值
- [NOIp 2014]联合权值
- noip2014 洛谷1351 联合权值
- Jzoj3931【NOIP2014day1官方数据】联合权值
- NOIP2014 联合权值
- 【NOIP 2014 Day1 T2】联合权值(......加法结合律QAQ)
- [NOIP2014]联合权值 题解
- NOIP 2014 T2 联合权值 DFS
- noip2014 联合权值 (树形结构)
- 3728 联合权值[NOIP 2014 Day1 T2]
- 【NOIP2014 Day1 T2】联合权值