[APIO2012]派遣

來源:互聯網
上載者:User

標籤:can   滿意度   最大   roo   傳遞   type   輸入輸出格式   總數   超過   

題目背景

在一個忍者的幫派裡,一些忍者們被選中派遣給顧客,然後依據自己的工作擷取報償。

題目描述

在這個幫派裡,有一名忍者被稱之為Master。除了Master以外,每名忍者都有且僅有一個上級。為保密,同時增強忍者們的領導力,所有與他們工作相關的指令總是由上級發送給他的直屬員工,而不允許通過其他的方式發送。

現在你要招募一批忍者,並把它們派遣給顧客。你需要為每個被派遣的忍者支付一定的薪水,同時使得支付的薪水總額不超過你的預算。另外,為了發送指令,你需要選擇一名忍者作為管理者,要求這個管理者可以向所有被派遣的忍者發送指令,在發送指令時,任何忍者(不管是否被派遣)都可以作為訊息的傳遞人。管理者自己可以被派遣,也可以不被派遣。當然,如果管理者沒有被排遣,你就不需要支付管理者的薪水。

你的目標是在預算內使顧客的滿意度最大。這裡定義顧客的滿意度為派遣的忍者總數乘以管理者的領導力水平,其中每個忍者的領導力水平也是一定的。

寫一個程式,給定每一個忍者i的上級Bi,薪水Ci,領導力Li,以及支付給忍者們的薪水總預算M,輸出在預算內滿足上述要求時顧客滿意度的最大值。

輸入輸出格式輸入格式:

第一行包含兩個整數N和M,其中N表示忍者的個數,M表示薪水的總預算。

接下來N行描述忍者們的上級、薪水以及領導力。其中的第i行包含三個整數Bi,Ci,Li分別表示第i個忍者的上級,薪水以及領導力。Master滿足Bi=0,並且每一個忍者的老闆的編號一定小於自己的編號Bi<i。

輸出格式:

輸出一個數,表示在預算內顧客的滿意度的最大值。

輸入輸出範例輸入範例#1: 
5 40 3 31 3 52 2 21 2 42 3 1
輸出範例#1: 
6
說明

1 ≤ N ≤ 100,000 忍者的個數;

1 ≤ M ≤ 1,000,000,000 薪水總預算;

0 ≤ Bi < i 忍者的上級的編號;

1 ≤ Ci ≤ M 忍者的薪水;

1 ≤ Li ≤ 1,000,000,000 忍者的領導力水平。

對於 30%的資料,N ≤ 3000。

 

 

 

蜜汁MLE...仍然不知道我為什麼把一個函數刪了之後就AC了..好迷...

我們在每個點維護一個左偏樹, 對這個樹進行dfs, 回溯的時候合并它和父親的左偏樹。

我們的左偏樹是一個大根堆,因為如果我們在一個點上的左偏樹裡的左右的值得和大於m,我們就必須刪掉一些點。

而我們刪掉價值更大的點,就可以保留更多的點。

所以知道左偏樹的值得和小於m,我們不停的del它的根,同時siz-1,然後這個點的答案就是L[x] * siz[x].

對於所有的答案取max就行了。

 

 

#include <iostream>#include <cstdio>#include<cstdlib>using namespace std;#define N 100005typedef long long ll;int n;ll m;struct edge{    int nxt, to;}ed[N];int head[N], cnt;inline void add(int x, int y){    ed[++cnt] = (edge){head[x], y};    head[x] = cnt;}int ch[N][2], root[N], sz[N];int R;ll sum[N], dis[N], val[N], L[N];ll ans;int Merge(int x, int y){    if (x * y == 0) return x + y;    if (val[x] < val[y]) swap(x, y);//大根堆     ch[x][1] = Merge(ch[x][1], y);    if (dis[ch[x][0]] < dis[ch[x][1]]) swap(ch[x][0], ch[x][1]);    dis[x] = dis[ch[x][1]] + 1;    return x;}inline void del(int x){    val[x] = -1;    root[x] = Merge(ch[x][0], ch[x][1]);}//del這個函數我手寫在dfs裡就A了,仍然不知道為何,求大神指點,萬分感謝void dfs(int x){    root[x] = x, sum[x] = val[x], sz[x] = 1;    for (int i = head[x] ; i ; i = ed[i].nxt)    {        int to = ed[i].to;        dfs(to);        sum[x] += sum[to], sz[x] += sz[to];        root[x] = Merge(root[x], root[to]) ;    }    while(sum[x] > m and sz[x])    {        sum[x] -= val[root[x]];        root[x] = Merge(ch[root[x]][0], ch[root[x]][1]);        sz[x]--;    }    ans = max(ans, L[x] * sz[x]);}signed main(){    scanf("%d%lld", &n, &m);    for (int i = 1 ; i <= n ; i ++)    {        int x;        scanf("%d%lld%lld", &x, &val[i], &L[i]);        if (!x) R = i;        add(x, i);    }    dfs(R);     cout << ans << endl;    return 0;}

 

[APIO2012]派遣

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.