APIO2012 派遣 可並堆 (D11)

2022-08-01 18:06:14 字數 1426 閱讀 4488

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

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

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

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

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

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

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

1 ≤ ci ≤ m 忍者的薪水;

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

可以想到貪心的思路,對於每個節點,找他及其子樹薪水最小的一些,加起來不超過m;

這時就可以運用到可並堆了,左偏樹是其中一種實現方式。

我還不怎麼會,可以看看這個

#includeusing

namespace

std;

//左偏樹

#define ll long long

const

int maxn=100005

;int

n;ll m,ans;

int root[maxn],ls[maxn],rs[maxn],dis[maxn];//

root:i及其子樹形成的大根堆的根 dis:i到外節點的距離

ll sum[maxn],size[maxn];//

i及其子樹形成的根的薪水和、人數

struct

persona[maxn];

template

inline void read(t &x)

}void build(int

x) int merge(int a,int

b)int

main();

build(i);

//自身成為乙個堆

ans=max(ans,z);

}for(int i=n;i;i--)

ans=max(ans,a[f].power*size[f]);

}printf(

"%lld

",ans);

}

view code

還可以用可合併值域線段樹,現在還不會,之後再寫。

APIO2012 派遣 題解

這題還是非常顯然的 題意大概是隨便選乙個點x,樹上每點有點權 v x 和乙個代價 c x 你有乙個值m,設,我們用m可以最多大於y x 個x的子樹中代價的和,求出所有點的y x v x 的值,其中最大值就是答案。非常顯然用線段樹合併 還有可並堆的做法,不怎麼會會,下次學 include includ...

APIO2012 派遣 解題報告

問題描述 在乙個忍者的幫派裡,一些忍者們被選中派遣給顧客,然後依據自己的工作獲取報償。在這個幫派裡,有一名忍者被稱之為master。除了master以外,每名忍者都有且僅有乙個上級。為保密,同時增強忍者們的領導力,所有與他們工作相關的指令總是由上級傳送給他的直接下屬,而不允許通過其他的方式傳送。現在...

APIO2012 派遣 左偏樹

題面 考慮列舉每個節點作為管理者,計算所獲得的滿意程度以更新答案。對於每個節點的計算,貪心,維護乙個大根堆,每次彈出薪水最大的人。這裡注意,一旦乙個人被彈出,那麼不再可能出現在其祖先們的最優解裡 廢話 所以使用可並堆左偏樹優化複雜度。include include define maxn 10001...