洛谷 P3177 HAOI2015 樹上染色

2022-05-08 17:42:13 字數 1069 閱讀 2227

有一棵點數為 \(n\) 的樹,樹邊有邊權。給你乙個在 \(0~ n\) 之內的正整數 \(k\) ,你要在這棵樹中選擇 \(k\)個點,將其染成黑色,並將其他 的\(n-k\)個點染成白色 。 將所有點染色後,你會獲得黑點兩兩之間的距離加上白點兩兩之間的距離的和的受益。問受益最大值是多少。

有點難想的dp 我果然太菜了

%%%__stdcall

\(f[i][j]\) 為以\(i\)為根的子樹, 選了染了\(j\)個黑點的最大貢獻

然後就是樹形揹包。。

siz[u]為以u為根的子樹大小

for (int j = min(k, siz[u]); j >= 0; j--)

for (int k = 0; k <= min(j, siz[v]); k++)

if (f[u][j-k] >= 0)

貢獻為子樹貢獻加上該邊的貢獻(子樹黑點個數 * 其它黑點個數 * 邊權 + 子樹白點個數 * 其它白點個數 * 邊權 )

#include#define ll long long

#define rg register

using namespace std;

inline int gi()

const int n = 2010;

struct node g[n<<1];

int last[n], gl;

inline void add(int z, int x, int y) ;

last[x] = gl;

g[++gl] = (node) ;

last[y] = gl;

return ;

}int siz[n], n, k;

long long f[n][n];

inline void init(int u, int fa)

return ;

}#define min(x, y) ((xy)?x:y)

inline void dfs(int u, int fa)

}return ;

}int main()

洛谷 P3177 HAOI2015 樹上染色

懶得複製題面了直接傳送門吧 直接求點與點之間的距離感覺不是很好求,所以我們考慮換乙個求法。瞄了一眼題解 距離跟路徑上邊的長度有關,所以我們直接來看每一條邊的貢獻吧 這誰想得到啊 對於每一條邊,它的貢獻等於 一邊的白點數 另一邊的白點數 一邊的黑點數 另一邊的黑點數 邊權 然後。我又卡住了。再次瞄題解...

HAOI2015 樹上染色 洛谷 3177

然後無根樹轉有根樹。設f x j 表示以x為根的子樹,選取了j個黑點,連線x和father x 的這條邊最大的貢獻。然後揹包一下就好了。詳細一點,對於這條邊。子樹下有 j 個黑點,那麼在其他位置就有k j個黑點,所以由於黑點這條邊被走過j k j 次。子樹下有si ze x j 個白點,其他位置有n...

洛谷P3177 樹上染色

題目 一道非常好的樹形dp。狀態 dp u n 為u的子樹選n個黑點所能得到的收益最大值。則最終的結果就是 dp root k root 可以為任何值,為了方便,使 root 1 然後考慮怎麼狀態轉移,狀態轉移一般要從方程和邊界入手,考慮用揹包的思想,得到方程 dp now j max dp now...