题目描述 Protoss 的灵能矩阵由若干个节点所构成。它们构成了一棵有根树,树根为1 号节点。定义没有子节点的节点为叶节点。叶节点内储存着一定量的能量,而非叶节点的能量为它子树中所有叶节点的能量之和。 如果一个节点的每一个子节点的能量都相同,那么这个节点就是能量平衡的。如果矩阵内每一个节点都能量平衡,则这个矩阵是能量平衡的。 被你所接管的这个灵能矩阵,似乎在长期的废弃之后已经无法保持的能量的平衡。为了重新让矩阵平衡,你可以通过将叶节点储存的能量散逸到太空中。你不可以使一个叶节点储存的能量为负数。 你希望求出最少散逸多少能量到太空中就能使灵能矩阵的能量平衡。
思路
因为每一个节点修改的后的值一定要是所有叶子节点的倍数的值,否则就会因无法品均而无法分配到每一个叶子点。然后暴力一下dfs就可以了#include#define maxn 200005 #define min(x, y) (x) < (y) ? (x) : (y) #define max(x, y) (x) > (y) ? (x) : (y) struct edge { long long to, next; }e[maxn]; long long ls[maxn], n, a[maxn], son[maxn]; bool v[maxn]; long long ans = 0; long long read() { long long x = 0; char ch = getchar(); while (ch < '0' || ch > '9') ch = getchar(); while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch -'0'; ch = getchar();} return x; } long long gcd(long long a, long long b) { if (b == 0) return a; return gcd(b, a % b); } long long lcm(long long a, long long b) { return a / gcd(a, b) * b; } long long find(long long now) { v[now] = 1; if (a[now] != 0) { son[now] = 1; return 0; } long long tot = 0, minn = 0x7fffffffffffffffll, sum = 0; son[now] = 1; for (long long i = ls[now]; i; i = e[i].next) if (v[e[i].to] == 0) { find(e[i].to); sum += a[e[i].to]; tot++; minn = min(minn, a[e[i].to]); son[now] = lcm(son[e[i].to], son[now]); } son[now] *= tot; long long m = minn - (minn % (son[now] / tot)); ans += sum - m * tot; a[now] = m * tot; return 0; } int main() { freopen("pylon.in", "r" ,stdin); freopen("pylon.out", "w", stdout); n = read(); for (long long i = 1; i <= n; i++) a[i] = read(); long long l = 0; for (long long i = 1; i < n; i++) { long long x = read(), y = read(); e[++l] = {y, ls[x]}; ls[x] = l; e[++l] = {x, ls[y]}; ls[y] = l; } find(1); printf("%lld\n", ans); }
]]>
Comments NOTHING