码迷,mamicode.com
首页 > 其他好文 > 详细

jzoj 3519_灵能矩阵_模拟

时间:2017-07-14 23:13:41      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:修改   平衡   define   min   stdio.h   getc   char   find   zoj   

题目描述

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_灵能矩阵_模拟

标签:修改   平衡   define   min   stdio.h   getc   char   find   zoj   

原文地址:http://www.cnblogs.com/nidhogg/p/7172393.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!