【問題描述】
在乙個忍者的幫派裡,些們被選中遣給在乙個忍者的幫派裡,些們被選中遣給顧客,然後依據自己的工作顧客,然後依據自己的工作獲取報償。
在這個幫派裡,有一名忍者被稱之為mastermaster。除了。除了mastermaster以外,每名忍者以外,每名忍者都有且僅乙個上級。為保密。為保密,同時增強,同時增強忍者們的領導力,所有與他們工作相關的指令總是由上級傳送給他的直接下屬,而不允許通過其他的方式傳送。
現在你要招募一批忍者,並把它們派遣給顧客。你需要為每個被派遣的忍者支付一定的薪水,同時使得支付的薪水總額不超過你的預算。另外,為了傳送指令,你需要選擇一名忍者作為管理者,要求這個管理者可以向所有被派遣的忍者傳送指令,在傳送指令時,任何忍者(不管是否被派遣)都可以作為訊息的傳遞人。管理者自己可以被派遣,也可以不被派遣。當然,如果管理者沒有被派遣,你就不需要支付管理者的薪水。
你的目標是在預算內使顧客的滿意度最大。這裡定義顧客的滿意度為派遣的忍者總數乘以管理者的領導力,其中每個忍者的領導力也是一定的。
寫乙個程式,給定每乙個忍者i的上級bi,薪水ci,領導力li,以及支付給忍者們的薪水總預算m,輸出在預算內滿足上述要求時顧客滿意度的最大值。
【問題分析】
題目大意是給定一棵樹,每個點有花費和點權,在不超過給定花費的前提下選擇一顆子樹內的若干點使得根節點點權與選擇點的數量乘積最大。
思路:很明顯的貪心問題,對於一顆子樹內的點肯定是選擇花費最小的若干個,所以可以對每乙個節點維護乙個大根堆表示子樹內點的花費,然後更新堆,更新答案即可。
#include
#include
#include
using
namespace
std;
const
int n=100001;
struct zk edge[n];
struct zz heap[n];
struct gg tree[n];
int n,m,cnt,cnt_heap; long
long ans;
int first[n];
inline
int readin()
while(ch>='0'&&ch<='9')
return x*f;
}void add(int a,int b)
void read()
return;
}int build(int k)
int merge(int x,int y)
void dfs(int k)
while(tree[k].sum>m)
ans=max(ans,tree[k].size*tree[k].able);
return;
}int main()
堆之左偏樹
左偏樹 左偏堆 優勢 兩個左偏樹合併效率高o logn 外結點 乙個結點的孩子數不滿兩個,就稱之為外結點。距離 dist 每個節點上有個距離 dist 的屬性,dist的值為該結點到最近的外結點所經過的邊的個數。外結點的dist 0。空結點的dist 1。左偏樹定義 1.是一顆二叉樹。2.是個堆。3...
可並堆 左偏樹 斜堆
經典的二叉堆已經可以在 o log n 的複雜度的情況下維護堆這樣的資料結構,也有d 堆可以維護成 o log d n 雖然pop操作的複雜度是 o d log d n 然而這兩種堆不能滿足 o log n 的合併操作,它們的經常是 o n log n 即每次將乙個堆中的堆頂拿出來放到另乙個堆裡。雖...
左偏樹(可並堆)
左偏樹其實是一種可並堆,它可以 o log2 n o l og2n 合併兩個堆。那左偏?也就是說他左邊肯定有什麼東西比右邊大 別著急,在左偏樹上有乙個叫距離的東西 個點的距離,被定義為它子樹中離他最近的外節點到這個節點的距離 這與樹的深度不同 其中我們定義乙個節點為外節點,當且僅當這個節點的左子樹和...