AOJ 911 組隊分配 樹形DP

2022-08-29 06:15:12 字數 1383 閱讀 7820

---恢復內容開始---

有乙個n個節點n-1條邊組成的樹。

每個點看成乙個人,連線u和v的邊看成是「中意關係」,即u和v兩個人都想和對方組隊。每個人希望組隊的物件有可能有多個。

一支隊伍由且僅由兩個人組成,並且如果u和v組隊了,那麼u、v將不能和其他人再組成一支隊。

現在問你,這n個人最多能組成多少支隊伍。(允許某些人組不了隊)

第一行輸入乙個整數n,m(1<=n<=200000)

接下來n-1行,每行兩個整數u,v,表示u和v兩個人都想和對方組隊。

資料保證是乙個合法的樹。

輸出乙個整數,表示最多能組成多少支隊伍。

1 21 3

2 44 5

首先看到題面,其實很容易想到是一道樹形dp。但樹上的關係在比賽時間裡沒有想明白,導致沒有做出來。

對於每乙個節點,都有取或者不取兩個可能。分別用dp[k][1]和dp[k][0]來表示

然後就是節點之間的關係了,對於每乙個節點來說,若不取這個點,則肯定是對於每乙個子節點的取或者不取求乙個max

也就是 dp[k][0]+=max(dp[ v ] [ 1 ] , dp [ v ] [ 0 ] )  v是k的子節點

但對於dp[k][1]就有點麻煩了,因為如果要讓dp[k][1]成立,則必然有至少加上乙個子節點不取的情況。

1

void tree_dp(int k,int

last)216

}17 dp[k][1]=dp[k][0

];//如果第k個取不到,直接賦值給dp[k][1],對下一層決策無影響

18if

(flag)

19 dp[k][1]++;

20 }

1 #include2

using

namespace

std;

3const

int maxn=2e5+7;4

int dp[maxn][2],ans=0

;5 vectorg[maxn];

6void tree_dp(int k,int

last)721

}22 dp[k][1]=dp[k][0

];23

if(flag)

24 dp[k][1]++;25}

26int

main()

2739 tree_dp(1,1

);40

//for(int i=1;i<=n;++i)

41//

cout<42 ans=max(dp[1][0],dp[1][1

]);43 cout44return0;

45 }

---恢復內容結束---

SCOI2007 組隊 差分

題面 scoi2007 組隊 題解 一開始固定h然後找性質找了很久也沒有找到任何有用的東西。然後大佬告訴我乙個神奇的方法。首先我們化一波式子 設 h 表示高度的最小值,v 表示速度的最小值 a h i h b v i v le c ah i ah bv i bv le c 如果我們列舉 h i 那麼...

0002組隊參賽規則

quote 乙個參賽隊伍不能超過三人,可以擁有乙個替補。包括替補在內任何參賽隊員必須為高中畢業五年內,才可以參賽,也就是說研究生一年級的學生還可以參加。現在的問題是給你乙個隊伍,請判斷這個隊伍是否合法。輸入資料 輸入資料報括若干組,每一組包括有若干行,第一行為乙個整數n,為這個隊伍的人數,接著有n行...

20110805 組隊賽 f題

測試資料有多組,對於每組資料,第一行為乙個整數n 1 n 10000 表示表示式中數字的個數,其後的第i 1行每行有乙個整數表示xi的值 1 i n 1 xi 1000000000 對於每組資料,如果你能幫阿里巴巴開啟石門,輸出yes,否則輸出no。58421143579 yesno 這是劉汝佳黑書...