---恢復內容開始---
有乙個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]成立,則必然有至少加上乙個子節點不取的情況。
1void 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 #include2using
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 這是劉汝佳黑書...