1. 程式人生 > >jzoj 3519_靈能矩陣_模擬

jzoj 3519_靈能矩陣_模擬

分配 pen code 成了 include getchar() clu tdi 所有

題目描述

Protoss 的靈能矩陣由若幹個節點所構成。它們構成了一棵有根樹,樹根為1 號節點。定義沒有子節點的節點為葉節點。葉節點內儲存著一定量的能量,而非葉節點的能量為它子樹中所有葉節點的能量之和。

如果一個節點的每一個子節點的能量都相同,那麽這個節點就是能量平衡的。如果矩陣內每一個節點都能量平衡,則這個矩陣是能量平衡的。

被你所接管的這個靈能矩陣,似乎在長期的廢棄之後已經無法保持的能量的平衡。為了重新讓矩陣平衡,你可以通過將葉節點儲存的能量散逸到太空中。你不可以使一個葉節點儲存的能量為負數。

你希望求出最少散逸多少能量到太空中就能使靈能矩陣的能量平衡。


思路

因為每一個節點修改的後的值一定要是所有葉子節點的倍數的值,否則就會因無法品均而無法分配到每一個葉子點。然後暴力一下dfs就可以了


#include <stdio.h>
#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); }

jzoj 3519_靈能矩陣_模擬