樹形揹包小結

2022-04-30 20:48:08 字數 1129 閱讀 9775

已知(2+1)?種做法

分別是:

link

bzoj2427**

int sta[n], dfn[n], low[n], w[n], val[n], dp[n][505], n, m, top, w[n], v[n], fa[n], l[n], cnt[n], siz[n], bel[n], idx;

vint g[n];

bitsetins, vis;

void tarjan(int u)

else if (ins[*v]) low[u] = min(low[u], dfn[*v]);

} if (dfn[u] == low[u])

while (u != v);

}}void dfs(int u)

void init()

void solve()

} int ans = 0;

lo1(i, m) chmax(ans, dp[1][i]);

out, ans;}

int main()

dp(u res)表示選擇了根到u的路徑上的所有點 再在u左側(已經遍歷過的部分)和u的子樹內選擇重量最大為res的物品的最大價值

bzoj2427**

w[n], val[n], dp[n][505], n, m, top, w[n], v[n], fa[n], cnt[n], bel[n];

vint g[n];

bitsetins, vis;

void tarjan(int u)

else if (ins[*v]) low[u] = min(low[u], dfn[*v]);

} if (dfn[u] == low[u])

while (u != v);

}}void dp(int u, int res) }

void init()

void solve()

int main()

另一種在dfs過程中列舉i <- siz[u] to 0j <- 0 to siz[v]的做法 (好像跟上面兩種不通用,如果通用求指正)

乙個這個寫法的題目

樹形依賴揹包

問題大意 給出一棵樹,根節點為1,每個點有毒素和收穫。要求毒素不超過給定值的情況下使收穫最大。乙個點的父親節點被選取後這個點才能被選取。首先弄出dfs序,也記錄下每個點其子樹及自身的大小。每個點都能夠被選或不選,如果選了才會考慮它子樹。設f i j 表示dfs序上第i位上的點在其子樹及自身上選取了毒...

樹形揹包總結

目錄 2 有物品大小 3 物品大小為1,有k的限制。二 dfs序上dp 例題1例題2 例題3總結下 樹形揹包,就是說,在樹上選乙個包含根的連通塊,或揹包存在依賴關係 選父才能選子 或者需要知道每個點的子樹中選了多少 通常,我們有兩種方法 我們設 dp i,j 表示在i的子節點中選j個的狀態。在轉移時...

樹形揹包DP

include using namespace std const int n 310,m n 2 int h n ne m v m idx int w n int dp n n int n,m void add int a,int b void dfs int u for int j m j 0 ...