ZOJ 3734 LIKE vs CANDLE

LIKE vs CANDLE


Time Limit: 2 Seconds      Memory Limit: 65536 KB


A microblog caused a war recently -There's the war between LIKE and CANDLE.

As you see, there are N accounts are trying to show their supportof LIKE or CANDLE. The way they show the support is forwarding a microblog,which means you choose someone's microblog and repost it with some comment. Avalid support microblog is forwarding the original account's microblog or aother valid support microblog. We can assume that all accounts will forward themicroblog only once. Also, it is impossible for a microblog forwarding amicroblog that posts after it.

When the activity ends, someone will use asoftware to check these accounts and calculate a PowerPoint for LIKE andCANDLE. Specifically, each account will have a value based on some algorithm(you need not to care). The value will be added to LIKE if the account isvoting LIKE, vice versa. So easy, isn't it?

Edward is a programmer and he supportsLIKE. He found a bug in the software that used in the activity - He can spend X PowerPoint of LIKE to flip an account. When an account is flipped, itwill be seen as it votes the other side. For example, if Alice votes LIKE andthen it is flipped, the software will add the value to CANDLE. Of course, anaccount can be flipped for several times - If Alice is flipped again, it votesfor LIKE again. And if we called the account theflipped account (Notice it's only a concept indicates the account hasbeen flipped and not an attribute of an account), all accounts which forwarding theflipped account's microblog will also be flipped.

Soon, Edward found that someone uses thisbug before! Some accounts have been flipped already. He can't spend X PowerPoint to flip themanymore; instead, he need spend YPower Point to flip an account which has been flipped directlyby someone.

For the glory of the LIKE, please helpEdward to flip accounts so that the Power Point of LIKE can be larger than CANDLE as muchas possible.

You can spend PowerPoint as much as youlike, no matter the total Power Point of LIKE is negative or not.

Input

The input containsno more than 20 test cases. Notice there's no empty line between each test case.

For each test case, first line has threeintegers N (1 ≤ N ≤ 50000) - the number of the accounts, X (0 ≤ X ≤ 1000) and Y (0 ≤ Y ≤ 1000) - as the problem description. Theaccount is numbered from 1 to N and 0 represent the original account.

Following N lines, the ith line means the ith account. Each line has four integers: V (0 ≤ V ≤ 1000) - the value of the ith account, F (0 ≤ F  N) - which account did the ith account's forwarding account come from (0th microblog is original account'smicroblog), S (0 ≤ S ≤ 1) - the status of flipped (0 means nochanged, 1 means changed) and P (0 ≤ P ≤ 1) - the side the account supportswithout flipped (0 means LIKE, 1 means CANDLE).

The original microblog's account can't beflipped, and it hasn't the value and the support side.

Output

For each test case print an integer,represents the maximum result of the value of LIKE minus the value of CANDLE. Ifthe value of CANDLE is larger than the LIKE, then just output"HAHAHAOMG" (without quote).

Sample Input

4 3 2

5 0 0 0

3 1 0 1

4 2 1 0

1 2 0 0

Sample Output

8

题目大意:此题题意略坑啊。。。。。。再加之语体教,不知道能不能说清楚啊。告诉一个N表示一共被转发N次,如果此状态没有被别人翻动,那么翻动此状态就需要花费X,如果被别人翻动过,就只需要花费Y。同时,翻动一个点,以其为根节点的子树上的点都会翻动。如果,别人翻动了一个点,其子树跟着翻动,但其子树上的点不被视为被别人翻动过。

另外,每行的P,表示的是每条转发的原始状态,需要先进行别人的翻动之后,才进行计算。如例子,因为第三个点被别人翻动过了,那么进行计算的时候,他的状态就已经是1了。

那么,dp[i][0]表示以i为根节点的子树,i点不翻动的赞-蜡烛的最大值。dp[i][1]则表示以i为根节点的子树,i点进行翻动的赞-蜡烛的最大值。(这里所说的是否翻动是指,进行计算的时候是否进行翻动,与是否被别人翻动无关。同时,某子树的根节点翻动,子节点也视作被翻动)。用state传递是否被别人翻动过,来确定初始状态。

那么,dp[i][0] += max(dp[j][0] ,dp[j][1] – flip[j]?Y:X); dp[i][1] +=max(dp[j][1] ,dp[j][0]-flip[j]?Y:X).

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;

int n ,x ,y ,state;
int flip[50010] ,dp[50010][2] ,value[50010];
vector<int> v[50010];

void solve(int s)
{
    //根据上面节点是否被别人翻过,确定当前点的初始状态。输入值为原始状态,处理完别人翻动后的状态为初始状态
    if(flip[s])
    {
        state ^= 1;
    }
    if(state)
    {
        value[s] = -value[s];
    }
    //初始状态之后,不被翻动则为当前值,被翻动即变为当前值的相反数
    dp[s][0] = value[s];
    dp[s][1] = -value[s];
    for(int i = 0;i<v[s].size();i++)
    {
        solve(v[s][i]);
        dp[s][0] += max(dp[v[s][i]][0] ,dp[v[s][i]][1] - (flip[v[s][i]] ? y : x));
        dp[s][1] += max(dp[v[s][i]][1] ,dp[v[s][i]][0] - (flip[v[s][i]] ? y : x));
    }
    if(flip[s])
    {
        state ^= 1;
    }
}

int main()
{
    int pre ,index;
    while(~scanf("%d%d%d",&n,&x,&y))
    {
        state = 0;
        memset(dp,0,sizeof(dp));
        for(int i = 1;i<=n;i++)
        {
            scanf("%d%d%d%d",&value[i],&pre,&flip[i],&index);
            //赞为正,蜡烛为负
            if(index)
            {
                value[i] = -value[i];
            }
            v[pre].push_back(i);
        }
        solve(0);
        if(dp[0][0] < 0)
        {
            printf("HAHAHAOMG\n");
        }
        else
        {
            printf("%d\n",dp[0][0]);
        }
        for(int i = 0;i<=n;i++)
        {
            v[i].clear();
        }
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值