NOI 2002 貪吃的九頭龍

2022-03-30 01:43:07 字數 2104 閱讀 6802

\(\\\)

給出一棵 \(n\) 個節點的樹,邊有邊權,現要求你將這 \(n\) 個點劃分到 \(m\) 個集合,集合不許為空。

另要求 \(1\) 號集合必須包含 \(1\) 號點,並且 \(1\) 號集合的大小必須正好為 \(k\) 。

如果一條邊連線的兩個點屬於同乙個集合,則這條邊的邊權將被計入總代價。

問總代價最少為多少。

\(\\\)

分析題目性質。

首先我們保證能劃分出 \(m\) 個集合,即 \(n-k\ge m\)。

然後考慮每一條邊何時會產生代價。

為什麼第三條成立?

如果只有兩個集合顯然要產生代價。

如果多於兩個集合,也就是說這兩個不屬於 \(1\) 號集合的點都有多於一種的選擇屬於哪乙個集合。

而題目限制是不為空集,邊的代價產生條件是屬於同一集合,兩個條件沒有互相約數的地方。

也就是說,我們把一條邊的兩個端點分到兩個集合,不會與約束條件衝突,同時我們通過調整配對情況使得這條邊的代價沒有產生。

記得首先要特判。

然後問題就變為,樹上選 \(k\) 個點,如果有一條邊的兩個端點同時被選中,邊權會被計入代價,求代價最小 \((m>2)\)。

這不就是乙個揹包........

注意到特殊的計算方式需要我們同時知道父節點和葉節點的決策,所以:

設 \(f[i][j][0/1]\) 表示,以 \(i\) 為根的子樹中,選中 \(j\) 個點的最小代價,其中不選 \(/\) 選 \(i\) 號節點。

記 \(u\) 為當前的根節點, \(v\) 為列舉的子樹根節點,\(w\) 為當前邊的邊權,轉移有

\[f[u][j][0]=min(f[u][j][0],f[u][j-k][0]+min(f[v][k][1],f[v][k][0]))\\

f[u][j][1]=min(f[u][j][1],f[u][j-k][1]+min(f[v][k][1]+w,f[v][k][0]))

\]考慮把 \(m=2\) 的情況加入轉移。

其實只要在兩個都不選入 \(1\) 集合那裡特判一下就好了。

\[f[u][j][0]=min(f[u][j][0],f[u][j-k][0]+min(f[v][k][1],f[v][k][0]+w*[m==2]))\\

f[u][j][1]=min(f[u][j][1],f[u][j-k][1]+min(f[v][k][1]+w,f[v][k][0]))

\]但是這一轉移還有問題。

考慮我們處理完紅色部分子樹的答案之後,剩餘的黑色子樹部分的答案。

注意到由於取 \(min\) 的轉移,在列舉 \(k=0\) 的時候無論如何我們也不會加上右側子樹的答案。

但是一些情況裡 \((\)諸如 \(m=2)\) 這個答案顯然是不合法的。

所以我們列舉每一棵子樹的時候都先 \(copy\) 乙份轉移陣列,然後重置原陣列為 \(inf\) 就可以了。

貌似這個 \(trick\) 也叫多叉樹轉二叉樹?

\(\\\)

#include#include#include#include#include#include#include#define n 310

#define r register

#define gc getchar

using namespace std;

inline int rd()

while(isdigit(c))

return f?-x:x;

}int n,m,ktot,tot,hd[n],f[n][n][2],tmp[n][2];

struct edgee[n<<1];

inline void add(int u,int v,int w)

void dfs(int u,int fa)

}}int main()

for(r int i=1,u,v,w;i

memset(f,0x3f,sizeof(f));

dfs(1,0);

printf("%d\n",f[1][ktot][1]);

return 0;

}

NOI2002 貪吃的九頭龍

description 傳說中的九頭龍是一種特別貪吃的動物。雖然名字叫 九頭龍 但這只是說它出生的時候有九個頭,而在成長的過程中,它有時會長出很多的新頭,頭的總數會遠大於九,當然也會有舊頭因衰老而自己脫落。有一天,有m個腦袋的九頭龍看到一棵長有n個果子的果樹,喜出望外,恨不得一口把它全部吃掉。可是必...

NOI2002 貪吃的九頭龍

p2940貪吃的九頭龍 貪吃的九頭龍 dragon.pas c cpp 問題描述 傳說中的九頭龍是一種特別貪吃的動物。雖然名字叫 九頭龍 但這只是說它出生的時候有九個頭,而在成長的過程中,它有時會長出很多的新頭,頭的總數會遠大於九,當然也會有舊頭因衰老而自己脫落。有一天,有m個腦袋的九頭龍看到一棵長...

題解 NOI2002 貪吃的九頭龍

題目大意 有一棵樹,你需要將n個點染成m種顏色,且需滿足一下兩種條件 1.一號點必須是一號顏色,且一號顏色必須包含k個點 2.每種顏色必須包含至少乙個點 代價為若一條邊連線的顏色相同則得付出該邊的代價 求滿足以上兩種情況下的代價之和 首先,一眼看出是道樹dp題 然後日常套路,設f u j f u j...