[NOIP2015]联合权值
1、题面
2、总结
第一次回忆一下当年的题目。但是这道题已经做烂了,只是看还记得树遍历会写么。
然后我写了一下,有点费劲,交上去之后只有70,比较尴尬,看了下去年5月写的代码,发现完全不是一个感觉啊。。。什么鬼?为什么那个时候写得那么长啊。难道是我现在想错了什么?
结果我发现当年我交过一个70分的。。发现差别就在于有没有开long long。
SHIT。想了一上午。
3、代码
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 #define MAXN 200005 7 #define MOD 10007 8 9 #ifdef WIN32 10 #define LL "%I64d" 11 #else 12 #define LL "%lld" 13 #endif 14 15 typedef long long ll; 16 17 ll h[MAXN], w[MAXN], tot[MAXN], n, u, v, o, ans, maxv; 18 19 struct edge { 20 ll v, next; 21 } e[MAXN * 2]; 22 23 void add(ll u, ll v) { 24 o++, e[o] = (edge) {v, h[u]}, h[u] = o; 25 } 26 27 void work(ll x, ll fa) { 28 ll sonv = 0, tmax = 0, vmax; 29 for (ll o = h[x]; o; o = e[o].next) { 30 ll v = e[o].v; 31 sonv += w[v]; 32 if (tmax < w[v]) tmax = w[v], vmax = v; 33 } 34 for (ll o = h[x]; o; o = e[o].next) { 35 ll v = e[o].v; 36 if (v == fa) continue; 37 if (v != vmax) maxv = max(maxv, tmax * w[v]); 38 tot[v] += w[fa] + sonv - w[v], work(v, x); 39 maxv = max(maxv, w[v] * w[fa]); 40 } 41 } 42 43 int main() { 44 freopen("link.in", "r", stdin); 45 freopen("link.out", "w", stdout); 46 scanf(LL, &n); 47 for (ll i = 1; i < n; i++) scanf(LL " " LL, &u, &v), add(u, v), add(v, u); 48 for (ll i = 1; i <= n; i++) scanf(LL, &w[i]); 49 work(1, 0); 50 for (ll i = 1; i <= n; i++) (ans += w[i] * tot[i]) %= MOD; 51 printf(LL " " LL, maxv, ans); 52 return 0; 53 }
风格也差别比较大。